PageRenderTime 96ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/sdk/crypto/asn.cpp

https://gitlab.com/Ephemeral/Source
C++ | 597 lines | 503 code | 88 blank | 6 comment | 115 complexity | 7a8d93a88d97f884acb190cbf2d03893 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. if (v >> (8*sizeof(v)-7)) // v about to overflow
  201. BERDecodeError();
  202. v <<= 7;
  203. v += b & 0x7f;
  204. if (!(b & 0x80))
  205. return i;
  206. }
  207. }
  208. void OID::DEREncode(BufferedTransformation &bt) const
  209. {
  210. assert(m_values.size() >= 2);
  211. ByteQueue temp;
  212. temp.Put(byte(m_values[0] * 40 + m_values[1]));
  213. for (size_t i=2; i<m_values.size(); i++)
  214. EncodeValue(temp, m_values[i]);
  215. bt.Put(OBJECT_IDENTIFIER);
  216. DERLengthEncode(bt, temp.CurrentSize());
  217. temp.TransferTo(bt);
  218. }
  219. void OID::BERDecode(BufferedTransformation &bt)
  220. {
  221. byte b;
  222. if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
  223. BERDecodeError();
  224. size_t length;
  225. if (!BERLengthDecode(bt, length) || length < 1)
  226. BERDecodeError();
  227. if (!bt.Get(b))
  228. BERDecodeError();
  229. length--;
  230. m_values.resize(2);
  231. m_values[0] = b / 40;
  232. m_values[1] = b % 40;
  233. while (length > 0)
  234. {
  235. word32 v;
  236. size_t valueLen = DecodeValue(bt, v);
  237. if (valueLen > length)
  238. BERDecodeError();
  239. m_values.push_back(v);
  240. length -= valueLen;
  241. }
  242. }
  243. void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
  244. {
  245. OID oid(bt);
  246. if (*this != oid)
  247. BERDecodeError();
  248. }
  249. inline BufferedTransformation & EncodedObjectFilter::CurrentTarget()
  250. {
  251. if (m_flags & PUT_OBJECTS)
  252. return *AttachedTransformation();
  253. else
  254. return TheBitBucket();
  255. }
  256. void EncodedObjectFilter::Put(const byte *inString, size_t length)
  257. {
  258. if (m_nCurrentObject == m_nObjects)
  259. {
  260. AttachedTransformation()->Put(inString, length);
  261. return;
  262. }
  263. LazyPutter lazyPutter(m_queue, inString, length);
  264. while (m_queue.AnyRetrievable())
  265. {
  266. switch (m_state)
  267. {
  268. case IDENTIFIER:
  269. if (!m_queue.Get(m_id))
  270. return;
  271. m_queue.TransferTo(CurrentTarget(), 1);
  272. m_state = LENGTH; // fall through
  273. case LENGTH:
  274. {
  275. byte b;
  276. if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0)
  277. {
  278. m_queue.TransferTo(CurrentTarget(), 1);
  279. m_level--;
  280. m_state = IDENTIFIER;
  281. break;
  282. }
  283. ByteQueue::Walker walker(m_queue);
  284. bool definiteLength;
  285. if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength))
  286. return;
  287. m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition());
  288. if (!((m_id & CONSTRUCTED) || definiteLength))
  289. BERDecodeError();
  290. if (!definiteLength)
  291. {
  292. if (!(m_id & CONSTRUCTED))
  293. BERDecodeError();
  294. m_level++;
  295. m_state = IDENTIFIER;
  296. break;
  297. }
  298. m_state = BODY; // fall through
  299. }
  300. case BODY:
  301. m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining);
  302. if (m_lengthRemaining == 0)
  303. m_state = IDENTIFIER;
  304. }
  305. if (m_state == IDENTIFIER && m_level == 0)
  306. {
  307. // just finished processing a level 0 object
  308. ++m_nCurrentObject;
  309. if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT)
  310. AttachedTransformation()->MessageEnd();
  311. if (m_nCurrentObject == m_nObjects)
  312. {
  313. if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS)
  314. AttachedTransformation()->MessageEnd();
  315. if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS)
  316. AttachedTransformation()->MessageSeriesEnd();
  317. m_queue.TransferAllTo(*AttachedTransformation());
  318. return;
  319. }
  320. }
  321. }
  322. }
  323. BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
  324. : m_inQueue(inQueue), m_finished(false)
  325. {
  326. Init(asnTag);
  327. }
  328. BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
  329. : m_inQueue(inQueue), m_finished(false)
  330. {
  331. Init(asnTag);
  332. }
  333. void BERGeneralDecoder::Init(byte asnTag)
  334. {
  335. byte b;
  336. if (!m_inQueue.Get(b) || b != asnTag)
  337. BERDecodeError();
  338. if (!BERLengthDecode(m_inQueue, m_length, m_definiteLength))
  339. BERDecodeError();
  340. if (!m_definiteLength && !(asnTag & CONSTRUCTED))
  341. BERDecodeError(); // cannot be primitive and have indefinite length
  342. }
  343. BERGeneralDecoder::~BERGeneralDecoder()
  344. {
  345. try // avoid throwing in constructor
  346. {
  347. if (!m_finished)
  348. MessageEnd();
  349. }
  350. catch (...)
  351. {
  352. }
  353. }
  354. bool BERGeneralDecoder::EndReached() const
  355. {
  356. if (m_definiteLength)
  357. return m_length == 0;
  358. else
  359. { // check end-of-content octets
  360. word16 i;
  361. return (m_inQueue.PeekWord16(i)==2 && i==0);
  362. }
  363. }
  364. byte BERGeneralDecoder::PeekByte() const
  365. {
  366. byte b;
  367. if (!Peek(b))
  368. BERDecodeError();
  369. return b;
  370. }
  371. void BERGeneralDecoder::CheckByte(byte check)
  372. {
  373. byte b;
  374. if (!Get(b) || b != check)
  375. BERDecodeError();
  376. }
  377. void BERGeneralDecoder::MessageEnd()
  378. {
  379. m_finished = true;
  380. if (m_definiteLength)
  381. {
  382. if (m_length != 0)
  383. BERDecodeError();
  384. }
  385. else
  386. { // remove end-of-content octets
  387. word16 i;
  388. if (m_inQueue.GetWord16(i) != 2 || i != 0)
  389. BERDecodeError();
  390. }
  391. }
  392. size_t BERGeneralDecoder::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
  393. {
  394. if (m_definiteLength && transferBytes > m_length)
  395. transferBytes = m_length;
  396. size_t blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
  397. ReduceLength(transferBytes);
  398. return blockedBytes;
  399. }
  400. size_t BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
  401. {
  402. if (m_definiteLength)
  403. end = STDMIN(m_length, end);
  404. return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
  405. }
  406. lword BERGeneralDecoder::ReduceLength(lword delta)
  407. {
  408. if (m_definiteLength)
  409. {
  410. if (m_length < delta)
  411. BERDecodeError();
  412. m_length -= delta;
  413. }
  414. return delta;
  415. }
  416. DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
  417. : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
  418. {
  419. }
  420. DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
  421. : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
  422. {
  423. }
  424. DERGeneralEncoder::~DERGeneralEncoder()
  425. {
  426. try // avoid throwing in constructor
  427. {
  428. if (!m_finished)
  429. MessageEnd();
  430. }
  431. catch (...)
  432. {
  433. }
  434. }
  435. void DERGeneralEncoder::MessageEnd()
  436. {
  437. m_finished = true;
  438. lword length = CurrentSize();
  439. m_outQueue.Put(m_asnTag);
  440. DERLengthEncode(m_outQueue, length);
  441. TransferTo(m_outQueue);
  442. }
  443. // *************************************************************
  444. void X509PublicKey::BERDecode(BufferedTransformation &bt)
  445. {
  446. BERSequenceDecoder subjectPublicKeyInfo(bt);
  447. BERSequenceDecoder algorithm(subjectPublicKeyInfo);
  448. GetAlgorithmID().BERDecodeAndCheck(algorithm);
  449. bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
  450. algorithm.MessageEnd();
  451. BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
  452. subjectPublicKey.CheckByte(0); // unused bits
  453. BERDecodePublicKey(subjectPublicKey, parametersPresent, (size_t)subjectPublicKey.RemainingLength());
  454. subjectPublicKey.MessageEnd();
  455. subjectPublicKeyInfo.MessageEnd();
  456. }
  457. void X509PublicKey::DEREncode(BufferedTransformation &bt) const
  458. {
  459. DERSequenceEncoder subjectPublicKeyInfo(bt);
  460. DERSequenceEncoder algorithm(subjectPublicKeyInfo);
  461. GetAlgorithmID().DEREncode(algorithm);
  462. DEREncodeAlgorithmParameters(algorithm);
  463. algorithm.MessageEnd();
  464. DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
  465. subjectPublicKey.Put(0); // unused bits
  466. DEREncodePublicKey(subjectPublicKey);
  467. subjectPublicKey.MessageEnd();
  468. subjectPublicKeyInfo.MessageEnd();
  469. }
  470. void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt)
  471. {
  472. BERSequenceDecoder privateKeyInfo(bt);
  473. word32 version;
  474. BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); // check version
  475. BERSequenceDecoder algorithm(privateKeyInfo);
  476. GetAlgorithmID().BERDecodeAndCheck(algorithm);
  477. bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
  478. algorithm.MessageEnd();
  479. BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
  480. BERDecodePrivateKey(octetString, parametersPresent, (size_t)privateKeyInfo.RemainingLength());
  481. octetString.MessageEnd();
  482. if (!privateKeyInfo.EndReached())
  483. BERDecodeOptionalAttributes(privateKeyInfo);
  484. privateKeyInfo.MessageEnd();
  485. }
  486. void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const
  487. {
  488. DERSequenceEncoder privateKeyInfo(bt);
  489. DEREncodeUnsigned<word32>(privateKeyInfo, 0); // version
  490. DERSequenceEncoder algorithm(privateKeyInfo);
  491. GetAlgorithmID().DEREncode(algorithm);
  492. DEREncodeAlgorithmParameters(algorithm);
  493. algorithm.MessageEnd();
  494. DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
  495. DEREncodePrivateKey(octetString);
  496. octetString.MessageEnd();
  497. DEREncodeOptionalAttributes(privateKeyInfo);
  498. privateKeyInfo.MessageEnd();
  499. }
  500. void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt)
  501. {
  502. DERReencode(bt, m_optionalAttributes);
  503. }
  504. void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const
  505. {
  506. m_optionalAttributes.CopyTo(bt);
  507. }
  508. NAMESPACE_END
  509. #endif