PageRenderTime 47ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Crypto/Source/Dll/asn.cpp

https://bitbucket.org/ryall/games-pikpik
C++ | 595 lines | 501 code | 88 blank | 6 comment | 114 complexity | fff66428509e56067d2d065c2bb28daa MD5 | raw file
  1. // asn.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #ifndef CRYPTOPP_IMPORTS
  4. #include "asn.h"
  5. #include <iomanip>
  6. #include <time.h>
  7. NAMESPACE_BEGIN(CryptoPP)
  8. USING_NAMESPACE(std)
  9. /// DER Length
  10. size_t DERLengthEncode(BufferedTransformation &bt, lword length)
  11. {
  12. size_t i=0;
  13. if (length <= 0x7f)
  14. {
  15. bt.Put(byte(length));
  16. i++;
  17. }
  18. else
  19. {
  20. bt.Put(byte(BytePrecision(length) | 0x80));
  21. i++;
  22. for (int j=BytePrecision(length); j; --j)
  23. {
  24. bt.Put(byte(length >> (j-1)*8));
  25. i++;
  26. }
  27. }
  28. return i;
  29. }
  30. bool BERLengthDecode(BufferedTransformation &bt, lword &length, bool &definiteLength)
  31. {
  32. byte b;
  33. if (!bt.Get(b))
  34. return false;
  35. if (!(b & 0x80))
  36. {
  37. definiteLength = true;
  38. length = b;
  39. }
  40. else
  41. {
  42. unsigned int lengthBytes = b & 0x7f;
  43. if (lengthBytes == 0)
  44. {
  45. definiteLength = false;
  46. return true;
  47. }
  48. definiteLength = true;
  49. length = 0;
  50. while (lengthBytes--)
  51. {
  52. if (length >> (8*(sizeof(length)-1)))
  53. BERDecodeError(); // length about to overflow
  54. if (!bt.Get(b))
  55. return false;
  56. length = (length << 8) | b;
  57. }
  58. }
  59. return true;
  60. }
  61. bool BERLengthDecode(BufferedTransformation &bt, size_t &length)
  62. {
  63. lword lw;
  64. bool definiteLength;
  65. if (!BERLengthDecode(bt, lw, definiteLength))
  66. BERDecodeError();
  67. if (!SafeConvert(lw, length))
  68. BERDecodeError();
  69. return definiteLength;
  70. }
  71. void DEREncodeNull(BufferedTransformation &out)
  72. {
  73. out.Put(TAG_NULL);
  74. out.Put(0);
  75. }
  76. void BERDecodeNull(BufferedTransformation &in)
  77. {
  78. byte b;
  79. if (!in.Get(b) || b != TAG_NULL)
  80. BERDecodeError();
  81. size_t length;
  82. if (!BERLengthDecode(in, length) || length != 0)
  83. BERDecodeError();
  84. }
  85. /// ASN Strings
  86. size_t DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen)
  87. {
  88. bt.Put(OCTET_STRING);
  89. size_t lengthBytes = DERLengthEncode(bt, strLen);
  90. bt.Put(str, strLen);
  91. return 1+lengthBytes+strLen;
  92. }
  93. size_t DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
  94. {
  95. return DEREncodeOctetString(bt, str.begin(), str.size());
  96. }
  97. size_t BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
  98. {
  99. byte b;
  100. if (!bt.Get(b) || b != OCTET_STRING)
  101. BERDecodeError();
  102. size_t bc;
  103. if (!BERLengthDecode(bt, bc))
  104. BERDecodeError();
  105. str.resize(bc);
  106. if (bc != bt.Get(str, bc))
  107. BERDecodeError();
  108. return bc;
  109. }
  110. size_t BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str)
  111. {
  112. byte b;
  113. if (!bt.Get(b) || b != OCTET_STRING)
  114. BERDecodeError();
  115. size_t bc;
  116. if (!BERLengthDecode(bt, bc))
  117. BERDecodeError();
  118. bt.TransferTo(str, bc);
  119. return bc;
  120. }
  121. size_t DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag)
  122. {
  123. bt.Put(asnTag);
  124. size_t lengthBytes = DERLengthEncode(bt, str.size());
  125. bt.Put((const byte *)str.data(), str.size());
  126. return 1+lengthBytes+str.size();
  127. }
  128. size_t BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
  129. {
  130. byte b;
  131. if (!bt.Get(b) || b != asnTag)
  132. BERDecodeError();
  133. size_t bc;
  134. if (!BERLengthDecode(bt, bc))
  135. BERDecodeError();
  136. SecByteBlock temp(bc);
  137. if (bc != bt.Get(temp, bc))
  138. BERDecodeError();
  139. str.assign((char *)temp.begin(), bc);
  140. return bc;
  141. }
  142. /// ASN BitString
  143. size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits)
  144. {
  145. bt.Put(BIT_STRING);
  146. size_t lengthBytes = DERLengthEncode(bt, strLen+1);
  147. bt.Put((byte)unusedBits);
  148. bt.Put(str, strLen);
  149. return 2+lengthBytes+strLen;
  150. }
  151. size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
  152. {
  153. byte b;
  154. if (!bt.Get(b) || b != BIT_STRING)
  155. BERDecodeError();
  156. size_t bc;
  157. if (!BERLengthDecode(bt, bc))
  158. BERDecodeError();
  159. byte unused;
  160. if (!bt.Get(unused))
  161. BERDecodeError();
  162. unusedBits = unused;
  163. str.resize(bc-1);
  164. if ((bc-1) != bt.Get(str, bc-1))
  165. BERDecodeError();
  166. return bc-1;
  167. }
  168. void DERReencode(BufferedTransformation &source, BufferedTransformation &dest)
  169. {
  170. byte tag;
  171. source.Peek(tag);
  172. BERGeneralDecoder decoder(source, tag);
  173. DERGeneralEncoder encoder(dest, tag);
  174. if (decoder.IsDefiniteLength())
  175. decoder.TransferTo(encoder, decoder.RemainingLength());
  176. else
  177. {
  178. while (!decoder.EndReached())
  179. DERReencode(decoder, encoder);
  180. }
  181. decoder.MessageEnd();
  182. encoder.MessageEnd();
  183. }
  184. void OID::EncodeValue(BufferedTransformation &bt, word32 v)
  185. {
  186. for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
  187. bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
  188. bt.Put((byte)(v & 0x7f));
  189. }
  190. size_t OID::DecodeValue(BufferedTransformation &bt, word32 &v)
  191. {
  192. byte b;
  193. size_t i=0;
  194. v = 0;
  195. while (true)
  196. {
  197. if (!bt.Get(b))
  198. BERDecodeError();
  199. i++;
  200. v <<= 7;
  201. v += b & 0x7f;
  202. if (!(b & 0x80))
  203. return i;
  204. }
  205. }
  206. void OID::DEREncode(BufferedTransformation &bt) const
  207. {
  208. assert(m_values.size() >= 2);
  209. ByteQueue temp;
  210. temp.Put(byte(m_values[0] * 40 + m_values[1]));
  211. for (size_t i=2; i<m_values.size(); i++)
  212. EncodeValue(temp, m_values[i]);
  213. bt.Put(OBJECT_IDENTIFIER);
  214. DERLengthEncode(bt, temp.CurrentSize());
  215. temp.TransferTo(bt);
  216. }
  217. void OID::BERDecode(BufferedTransformation &bt)
  218. {
  219. byte b;
  220. if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
  221. BERDecodeError();
  222. size_t length;
  223. if (!BERLengthDecode(bt, length) || length < 1)
  224. BERDecodeError();
  225. if (!bt.Get(b))
  226. BERDecodeError();
  227. length--;
  228. m_values.resize(2);
  229. m_values[0] = b / 40;
  230. m_values[1] = b % 40;
  231. while (length > 0)
  232. {
  233. word32 v;
  234. size_t valueLen = DecodeValue(bt, v);
  235. if (valueLen > length)
  236. BERDecodeError();
  237. m_values.push_back(v);
  238. length -= valueLen;
  239. }
  240. }
  241. void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
  242. {
  243. OID oid(bt);
  244. if (*this != oid)
  245. BERDecodeError();
  246. }
  247. inline BufferedTransformation & EncodedObjectFilter::CurrentTarget()
  248. {
  249. if (m_flags & PUT_OBJECTS)
  250. return *AttachedTransformation();
  251. else
  252. return TheBitBucket();
  253. }
  254. void EncodedObjectFilter::Put(const byte *inString, size_t length)
  255. {
  256. if (m_nCurrentObject == m_nObjects)
  257. {
  258. AttachedTransformation()->Put(inString, length);
  259. return;
  260. }
  261. LazyPutter lazyPutter(m_queue, inString, length);
  262. while (m_queue.AnyRetrievable())
  263. {
  264. switch (m_state)
  265. {
  266. case IDENTIFIER:
  267. if (!m_queue.Get(m_id))
  268. return;
  269. m_queue.TransferTo(CurrentTarget(), 1);
  270. m_state = LENGTH; // fall through
  271. case LENGTH:
  272. {
  273. byte b;
  274. if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0)
  275. {
  276. m_queue.TransferTo(CurrentTarget(), 1);
  277. m_level--;
  278. m_state = IDENTIFIER;
  279. break;
  280. }
  281. ByteQueue::Walker walker(m_queue);
  282. bool definiteLength;
  283. if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength))
  284. return;
  285. m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition());
  286. if (!((m_id & CONSTRUCTED) || definiteLength))
  287. BERDecodeError();
  288. if (!definiteLength)
  289. {
  290. if (!(m_id & CONSTRUCTED))
  291. BERDecodeError();
  292. m_level++;
  293. m_state = IDENTIFIER;
  294. break;
  295. }
  296. m_state = BODY; // fall through
  297. }
  298. case BODY:
  299. m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining);
  300. if (m_lengthRemaining == 0)
  301. m_state = IDENTIFIER;
  302. }
  303. if (m_state == IDENTIFIER && m_level == 0)
  304. {
  305. // just finished processing a level 0 object
  306. ++m_nCurrentObject;
  307. if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT)
  308. AttachedTransformation()->MessageEnd();
  309. if (m_nCurrentObject == m_nObjects)
  310. {
  311. if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS)
  312. AttachedTransformation()->MessageEnd();
  313. if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS)
  314. AttachedTransformation()->MessageSeriesEnd();
  315. m_queue.TransferAllTo(*AttachedTransformation());
  316. return;
  317. }
  318. }
  319. }
  320. }
  321. BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
  322. : m_inQueue(inQueue), m_finished(false)
  323. {
  324. Init(asnTag);
  325. }
  326. BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
  327. : m_inQueue(inQueue), m_finished(false)
  328. {
  329. Init(asnTag);
  330. }
  331. void BERGeneralDecoder::Init(byte asnTag)
  332. {
  333. byte b;
  334. if (!m_inQueue.Get(b) || b != asnTag)
  335. BERDecodeError();
  336. if (!BERLengthDecode(m_inQueue, m_length, m_definiteLength))
  337. BERDecodeError();
  338. if (!m_definiteLength && !(asnTag & CONSTRUCTED))
  339. BERDecodeError(); // cannot be primitive and have indefinite length
  340. }
  341. BERGeneralDecoder::~BERGeneralDecoder()
  342. {
  343. try // avoid throwing in constructor
  344. {
  345. if (!m_finished)
  346. MessageEnd();
  347. }
  348. catch (...)
  349. {
  350. }
  351. }
  352. bool BERGeneralDecoder::EndReached() const
  353. {
  354. if (m_definiteLength)
  355. return m_length == 0;
  356. else
  357. { // check end-of-content octets
  358. word16 i;
  359. return (m_inQueue.PeekWord16(i)==2 && i==0);
  360. }
  361. }
  362. byte BERGeneralDecoder::PeekByte() const
  363. {
  364. byte b;
  365. if (!Peek(b))
  366. BERDecodeError();
  367. return b;
  368. }
  369. void BERGeneralDecoder::CheckByte(byte check)
  370. {
  371. byte b;
  372. if (!Get(b) || b != check)
  373. BERDecodeError();
  374. }
  375. void BERGeneralDecoder::MessageEnd()
  376. {
  377. m_finished = true;
  378. if (m_definiteLength)
  379. {
  380. if (m_length != 0)
  381. BERDecodeError();
  382. }
  383. else
  384. { // remove end-of-content octets
  385. word16 i;
  386. if (m_inQueue.GetWord16(i) != 2 || i != 0)
  387. BERDecodeError();
  388. }
  389. }
  390. size_t BERGeneralDecoder::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
  391. {
  392. if (m_definiteLength && transferBytes > m_length)
  393. transferBytes = m_length;
  394. size_t blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
  395. ReduceLength(transferBytes);
  396. return blockedBytes;
  397. }
  398. size_t BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
  399. {
  400. if (m_definiteLength)
  401. end = STDMIN(m_length, end);
  402. return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
  403. }
  404. lword BERGeneralDecoder::ReduceLength(lword delta)
  405. {
  406. if (m_definiteLength)
  407. {
  408. if (m_length < delta)
  409. BERDecodeError();
  410. m_length -= delta;
  411. }
  412. return delta;
  413. }
  414. DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
  415. : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
  416. {
  417. }
  418. DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
  419. : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
  420. {
  421. }
  422. DERGeneralEncoder::~DERGeneralEncoder()
  423. {
  424. try // avoid throwing in constructor
  425. {
  426. if (!m_finished)
  427. MessageEnd();
  428. }
  429. catch (...)
  430. {
  431. }
  432. }
  433. void DERGeneralEncoder::MessageEnd()
  434. {
  435. m_finished = true;
  436. lword length = CurrentSize();
  437. m_outQueue.Put(m_asnTag);
  438. DERLengthEncode(m_outQueue, length);
  439. TransferTo(m_outQueue);
  440. }
  441. // *************************************************************
  442. void X509PublicKey::BERDecode(BufferedTransformation &bt)
  443. {
  444. BERSequenceDecoder subjectPublicKeyInfo(bt);
  445. BERSequenceDecoder algorithm(subjectPublicKeyInfo);
  446. GetAlgorithmID().BERDecodeAndCheck(algorithm);
  447. bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
  448. algorithm.MessageEnd();
  449. BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
  450. subjectPublicKey.CheckByte(0); // unused bits
  451. BERDecodePublicKey(subjectPublicKey, parametersPresent, (size_t)subjectPublicKey.RemainingLength());
  452. subjectPublicKey.MessageEnd();
  453. subjectPublicKeyInfo.MessageEnd();
  454. }
  455. void X509PublicKey::DEREncode(BufferedTransformation &bt) const
  456. {
  457. DERSequenceEncoder subjectPublicKeyInfo(bt);
  458. DERSequenceEncoder algorithm(subjectPublicKeyInfo);
  459. GetAlgorithmID().DEREncode(algorithm);
  460. DEREncodeAlgorithmParameters(algorithm);
  461. algorithm.MessageEnd();
  462. DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
  463. subjectPublicKey.Put(0); // unused bits
  464. DEREncodePublicKey(subjectPublicKey);
  465. subjectPublicKey.MessageEnd();
  466. subjectPublicKeyInfo.MessageEnd();
  467. }
  468. void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt)
  469. {
  470. BERSequenceDecoder privateKeyInfo(bt);
  471. word32 version;
  472. BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); // check version
  473. BERSequenceDecoder algorithm(privateKeyInfo);
  474. GetAlgorithmID().BERDecodeAndCheck(algorithm);
  475. bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
  476. algorithm.MessageEnd();
  477. BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
  478. BERDecodePrivateKey(octetString, parametersPresent, (size_t)privateKeyInfo.RemainingLength());
  479. octetString.MessageEnd();
  480. if (!privateKeyInfo.EndReached())
  481. BERDecodeOptionalAttributes(privateKeyInfo);
  482. privateKeyInfo.MessageEnd();
  483. }
  484. void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const
  485. {
  486. DERSequenceEncoder privateKeyInfo(bt);
  487. DEREncodeUnsigned<word32>(privateKeyInfo, 0); // version
  488. DERSequenceEncoder algorithm(privateKeyInfo);
  489. GetAlgorithmID().DEREncode(algorithm);
  490. DEREncodeAlgorithmParameters(algorithm);
  491. algorithm.MessageEnd();
  492. DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
  493. DEREncodePrivateKey(octetString);
  494. octetString.MessageEnd();
  495. DEREncodeOptionalAttributes(privateKeyInfo);
  496. privateKeyInfo.MessageEnd();
  497. }
  498. void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt)
  499. {
  500. DERReencode(bt, m_optionalAttributes);
  501. }
  502. void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const
  503. {
  504. m_optionalAttributes.CopyTo(bt);
  505. }
  506. NAMESPACE_END
  507. #endif