asn1.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. /*
  2. * Copyright 1998-2007 by egnite Software GmbH
  3. * Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  22. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  25. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  26. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  28. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * For additional information see http://www.ethernut.de/
  32. */
  33. #include <sys/types.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #ifndef WIN32
  37. #include <memdebug.h>
  38. #endif
  39. #include <pro/asn1.h>
  40. /*
  41. * Abstract Syntax Notation One, ASN.1 as defined in ISO/IS 8824 and
  42. * ISO/IS 8825. This implements a subset of the above international
  43. * standards that is sufficient for SNMP.
  44. */
  45. /*!
  46. * \brief Interpret the length of the current object.
  47. *
  48. * @param data Pointer to start of length field.
  49. * @param length Pointer to the variable that receives the value of this
  50. * length field.
  51. *
  52. * \return A pointer to the first byte after this length field (aka: the
  53. * start of the data field). Returns NULL on any error.
  54. */
  55. static const uint8_t *AsnLenParse(const uint8_t * data, uint32_t * length)
  56. {
  57. uint8_t lengthbyte = *data++;
  58. if (lengthbyte & ASN_LONG_LEN) {
  59. /* Long length. */
  60. lengthbyte &= ~ASN_LONG_LEN;
  61. if (lengthbyte == 0 || lengthbyte > sizeof(long)) {
  62. return NULL;
  63. }
  64. *length = 0;
  65. while (lengthbyte--) {
  66. *length <<= 8;
  67. *length |= *data++;
  68. }
  69. } else {
  70. /* Short length. */
  71. *length = lengthbyte;
  72. }
  73. return data;
  74. }
  75. /*!
  76. * \brief Build an ASN header for a specified length.
  77. *
  78. * \param data Pointer to start of the object.
  79. * \param datalength Contains the number of available bytes following
  80. * the start of the object. On exit, it is returned
  81. * as the number of available bytes following the
  82. * encoded length of this object.
  83. * \param length Length of object.
  84. *
  85. * \return A pointer to the first byte of the contents of this object.
  86. * Returns NULL on any error.
  87. */
  88. static uint8_t *AsnLenBuild(uint8_t * data, size_t * datalength, size_t length)
  89. {
  90. if (length < 0x80) {
  91. /* Check for buffer overflow. */
  92. if (*datalength < 1) {
  93. return NULL;
  94. }
  95. *datalength -= 1;
  96. *data++ = (uint8_t) length;
  97. } else if (length <= 0xFF) {
  98. /* Check for buffer overflow. */
  99. if (*datalength < 2) {
  100. return NULL;
  101. }
  102. *datalength -= 2;
  103. *data++ = (uint8_t) (0x01 | ASN_LONG_LEN);
  104. *data++ = (uint8_t) length;
  105. } else {
  106. /* Check for buffer overflow. */
  107. if (*datalength < 3) {
  108. return NULL;
  109. }
  110. *datalength -= 3;
  111. *data++ = (uint8_t) (0x02 | ASN_LONG_LEN);
  112. *data++ = (uint8_t) (((unsigned) length >> 8) & 0xFF);
  113. *data++ = (uint8_t) (length & 0xFF);
  114. }
  115. return data;
  116. }
  117. /*!
  118. * \brief Interpret the ID and length of the next object.
  119. *
  120. * \param data Pointer to start of the object.
  121. * \param datalength Contains the number of valid bytes following the
  122. * start of the object. On exit, it is returned as
  123. * the number of valid bytes following the ID and
  124. * length.
  125. * \param type Pointer to the variable that receives the ASN type
  126. * of the object.
  127. * \return A pointer to the first byte following ID and length (aka the
  128. * start of the data field). Returns NULL on any error.
  129. */
  130. const uint8_t *AsnHeaderParse(const uint8_t * data, size_t * datalength, uint8_t * type)
  131. {
  132. size_t header_len;
  133. uint32_t asn_length;
  134. const uint8_t *bufp = data;
  135. if (*datalength <= 0) {
  136. return NULL;
  137. }
  138. /*
  139. * The first byte of the header is the type. This only
  140. * works on data types < 30, i.e. no extension octets.
  141. */
  142. *type = *bufp;
  143. if ((*type & ASN_EXTENSION_ID) == ASN_EXTENSION_ID) {
  144. return NULL;
  145. }
  146. /*
  147. * Interpret the length (short or long) of this object.
  148. */
  149. if ((bufp = AsnLenParse(bufp + 1, &asn_length)) == NULL) {
  150. return NULL;
  151. }
  152. header_len = bufp - data;
  153. /* Data length exceeds packet size. */
  154. if (header_len + asn_length > *datalength) {
  155. return NULL;
  156. }
  157. *datalength = (int) asn_length;
  158. return bufp;
  159. }
  160. /*!
  161. * \brief Build an ASN header for an object with a given ID and length.
  162. *
  163. * This only works on data types < 30, i.e. no extension octets.
  164. * The maximum length is 0xFFFF;
  165. *
  166. * \param data Pointer to start of object.
  167. * \param datalength Contains the number of available bytes following
  168. * the start of the object. On exit, it is returned
  169. * as the number of available bytes following the
  170. * encoded ID and length of this object.
  171. * \param type ASN type of the object.
  172. * \param length Length of object.
  173. *
  174. * \return Returns a pointer to the first byte of the contents of this object.
  175. * Returns NULL on any error.
  176. */
  177. uint8_t *AsnHeaderBuild(uint8_t * data, size_t * datalength, uint8_t type, size_t length)
  178. {
  179. if (*datalength < 1) {
  180. return NULL;
  181. }
  182. *data++ = type;
  183. (*datalength)--;
  184. return AsnLenBuild(data, datalength, length);
  185. }
  186. /*!
  187. * \brief Check the type and get the length of the next object.
  188. *
  189. * Similare to AsnHeaderParse, but tests for expected type.
  190. *
  191. * \param data Pointer to start of the object.
  192. * \param datalength Contains the number of valid bytes following the
  193. * start of the object. On exit, it is returned as
  194. * the number of valid bytes following the ID and
  195. * length.
  196. * \param type The expected ASN type of the object.
  197. *
  198. * \return A pointer to the first byte following ID and length (aka the
  199. * start of the data field). Returns NULL on any error.
  200. */
  201. const uint8_t *AsnSequenceParse(const uint8_t * data, size_t * datalength, uint8_t type)
  202. {
  203. uint8_t t;
  204. if ((data = AsnHeaderParse(data, datalength, &t)) != NULL) {
  205. if (t != type) {
  206. data = NULL;
  207. }
  208. }
  209. return data;
  210. }
  211. /*!
  212. * \brief Build an ASN header for a sequence with a given type and length.
  213. *
  214. * This only works on data types < 30, i.e. no extension octets.
  215. * The maximum length is 0xFFFF;
  216. *
  217. * \param data Pointer to start of object.
  218. * \param datalength Contains the number of available bytes following
  219. * the start of the object. On exit, it is returned
  220. * as the number of available bytes following the
  221. * encoded ID and length of this object.
  222. * \param type ASN type of the object.
  223. * \param length Length of object.
  224. *
  225. * \return Returns a pointer to the first byte of the contents of this object.
  226. * Returns NULL on any error.
  227. */
  228. uint8_t *AsnSequenceBuild(uint8_t * data, size_t * datalength, uint8_t type, size_t length)
  229. {
  230. if (*datalength < 4) {
  231. /* Not enough space in output packet. */
  232. return NULL;
  233. }
  234. *datalength -= 4;
  235. *data++ = type;
  236. *data++ = (uint8_t) (0x02 | ASN_LONG_LEN);
  237. *data++ = (uint8_t) (((unsigned) length >> 8) & 0xFF);
  238. *data++ = (uint8_t) length;
  239. return data;
  240. }
  241. /*!
  242. * \brief Pull a long out of an ASN integer type.
  243. *
  244. * \param data Pointer to start of the object.
  245. * \param datalength Contains the number of valid bytes following the
  246. * start of the object. On exit, it is returned as
  247. * the number of valid bytes following the end of
  248. * this object.
  249. * \param type Pointer to the variable that receives the ASN type
  250. * of the object.
  251. * \param intp Pointer to the variable that receives the value
  252. * of the object.
  253. *
  254. * \return Pointer to the first byte past the end of this object
  255. * (i.e. the start of the next object). Returns NULL on any
  256. * error.
  257. */
  258. const uint8_t *AsnIntegerParse(const uint8_t * data, size_t * datalength, uint8_t * type, long *intp)
  259. {
  260. const uint8_t *bufp = data;
  261. uint32_t asn_length;
  262. /* Get the type. */
  263. *type = *bufp++;
  264. /* Parse the length. */
  265. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  266. return NULL;
  267. }
  268. /* Check for overflow. */
  269. if (asn_length > sizeof(long) || asn_length + (bufp - data) > *datalength) {
  270. return NULL;
  271. }
  272. /* Update the number of valid bytes. */
  273. *datalength -= asn_length + (bufp - data);
  274. /* Determine sign. */
  275. if (*bufp & 0x80) {
  276. *intp = -1;
  277. } else {
  278. *intp = 0;
  279. }
  280. /* Retrieve the value. */
  281. while (asn_length--) {
  282. *intp <<= 8;
  283. *intp |= *bufp++;
  284. }
  285. return bufp;
  286. }
  287. /*!
  288. * \brief Build an ASN object containing an integer.
  289. *
  290. * \param data Pointer to start of output buffer
  291. * \param datalength Contains the number of available bytes following
  292. * the start of the object. On exit, it is returned
  293. * as the number of available bytes following the end
  294. * of this object.
  295. * \param type ASN type of the object.
  296. * \param intp Value of the object.
  297. *
  298. * \return A pointer to the first byte past the end of this object
  299. * (i.e. the start of the next object). Returns NULL on any
  300. * error.
  301. */
  302. uint8_t *AsnIntegerBuild(uint8_t * data, size_t * datalength, uint8_t type, long *intp)
  303. {
  304. uint32_t mask;
  305. long value = *intp;
  306. size_t size = sizeof(long);
  307. /*
  308. * Truncate unnecessary bytes off of the most significant end of
  309. * this 2's complement integer. Skip any leading sequence of
  310. * 9 consecutive 1's or 0's.
  311. */
  312. mask = 0x1FFUL << ((8 * (sizeof(long) - 1)) - 1);
  313. while (((value & mask) == 0 || (value & mask) == mask) && size > 1) {
  314. size--;
  315. value <<= 8;
  316. }
  317. /* We know the size, so let's build the header. */
  318. if ((data = AsnHeaderBuild(data, datalength, type, size)) == NULL) {
  319. return NULL;
  320. }
  321. /* Check if there's enough space for the value. */
  322. if (*datalength < size) {
  323. return NULL;
  324. }
  325. *datalength -= size;
  326. /* Store the value, MSB first. */
  327. mask = 0xFFUL << (8 * (sizeof(long) - 1));
  328. while (size--) {
  329. *data++ = (uint8_t) ((value & mask) >> (8 * (sizeof(long) - 1)));
  330. value <<= 8;
  331. }
  332. return data;
  333. }
  334. /*!
  335. * \brief Pull an unsigned long out of an ASN integer type.
  336. *
  337. * \param data Pointer to start of the object.
  338. * \param datalength Contains the number of valid bytes following the
  339. * start of the object. On exit, it is returned as
  340. * the number of valid bytes following the end of
  341. * this object.
  342. * \param type Pointer to the variable that receives the ASN type
  343. * of the object.
  344. * \param intp Pointer to the variable that receives the value
  345. * of the object.
  346. *
  347. * \return Pointer to the first byte past the end of this object
  348. * (i.e. the start of the next object). Returns NULL on any
  349. * error.
  350. */
  351. const uint8_t *AsnUnsignedParse(const uint8_t * data, size_t * datalength, uint8_t * type, uint32_t * intp)
  352. {
  353. const uint8_t *bufp = data;
  354. uint32_t asn_length;
  355. /* Get the type. */
  356. *type = *bufp++;
  357. /* Parse the length. */
  358. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  359. return NULL;
  360. }
  361. /* Check for length overflow. */
  362. if (asn_length > sizeof(long) + 1 || (asn_length == sizeof(long) + 1 && *bufp != 0x00)) {
  363. return NULL;
  364. }
  365. /* Check for sufficient data. */
  366. if (asn_length + (bufp - data) > *datalength) {
  367. return NULL;
  368. }
  369. /* Update the number of valid bytes. */
  370. *datalength -= (int) asn_length + (bufp - data);
  371. /* Determine sign. */
  372. if (*bufp & 0x80) {
  373. *intp = -1;
  374. } else {
  375. *intp = 0;
  376. }
  377. /* Retrieve the value. */
  378. while (asn_length--) {
  379. *intp <<= 8;
  380. *intp |= *bufp++;
  381. }
  382. return bufp;
  383. }
  384. /*!
  385. * \brief Build an ASN object containing an unsigned integer.
  386. *
  387. * \param data Pointer to start of output buffer
  388. * \param datalength Contains the number of available bytes following
  389. * the start of the object. On exit, it is returned
  390. * as the number of available bytes following the end
  391. * of this object.
  392. * \param type ASN type of the object.
  393. * \param intp Value of the object.
  394. *
  395. * \return A pointer to the first byte past the end of this object
  396. * (i.e. the start of the next object). Returns NULL on any
  397. * error.
  398. */
  399. uint8_t *AsnUnsignedBuild(uint8_t * data, size_t * datalength, uint8_t type, uint32_t * intp)
  400. {
  401. int msb;
  402. uint32_t mask;
  403. uint32_t value = *intp;
  404. size_t size = sizeof(uint32_t);
  405. /* Check if MSB is set. */
  406. if (value & (0x80UL << (8 * (sizeof(long) - 1)))) {
  407. msb = 1;
  408. size++;
  409. } else {
  410. msb = 0;
  411. /*
  412. * Truncate unnecessary bytes off of the most significant end.
  413. * Skip any leading sequence of 9 consecutive 1's or 0's.
  414. */
  415. mask = 0x1FFUL << ((8 * (sizeof(long) - 1)) - 1);
  416. while ((((value & mask) == 0) || ((value & mask) == mask)) && size > 1) {
  417. size--;
  418. value <<= 8;
  419. }
  420. }
  421. /* We know the size, so let's build the header. */
  422. if ((data = AsnHeaderBuild(data, datalength, type, size)) == NULL) {
  423. return NULL;
  424. }
  425. /* Check if there's enough space for the value. */
  426. if (*datalength < size) {
  427. return NULL;
  428. }
  429. *datalength -= size;
  430. /* Add leading null byte if MSB set. */
  431. if (msb) {
  432. *data++ = '\0';
  433. size--;
  434. }
  435. /* Store the value, MSB first. */
  436. mask = 0xFFUL << (8 * (sizeof(long) - 1));
  437. while (size--) {
  438. *data++ = (uint8_t) ((value & mask) >> (8 * (sizeof(long) - 1)));
  439. value <<= 8;
  440. }
  441. return data;
  442. }
  443. /*!
  444. * \brief Pulls a string out of an ASN octet string type.
  445. *
  446. * \param data Pointer to start of the object.
  447. * \param datalength Contains the number of valid bytes following the
  448. * start of the object. On exit, it is returned as
  449. * the number of valid bytes following the end of
  450. * this object.
  451. * \param type Pointer to the variable that receives the ASN type
  452. * of the object.
  453. * \param string Pointer to the variable that receives the value
  454. * of the object.
  455. * \param strlength Contains the size of the string buffer on entry.
  456. * On exit, it is returned as the number of bytes
  457. * stored in the string buffer.
  458. *
  459. * \return Pointer to the first byte past the end of this object
  460. * (i.e. the start of the next object). Returns NULL on any
  461. * error.
  462. */
  463. const uint8_t *AsnOctetStringParse(const uint8_t * data, size_t * datalength, uint8_t * type, uint8_t * string, size_t * strlength)
  464. {
  465. const uint8_t *bufp = data;
  466. uint32_t asn_length;
  467. /* Get the type. */
  468. *type = *bufp++;
  469. /* Get the length. */
  470. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  471. return NULL;
  472. }
  473. /* Check for overflow. */
  474. if (asn_length > *strlength || asn_length + (bufp - data) > *datalength) {
  475. return NULL;
  476. }
  477. if (asn_length) {
  478. /* Store value and update lengths. */
  479. memcpy(string, bufp, asn_length);
  480. *strlength = (size_t) asn_length;
  481. }
  482. *datalength -= (size_t) (asn_length + (bufp - data));
  483. return bufp + asn_length;
  484. }
  485. /*!
  486. * \brief Build an ASN object containing an octet string.
  487. *
  488. * \param data Pointer to start of output buffer
  489. * \param datalength Contains the number of available bytes following
  490. * the start of the object. On exit, it is returned
  491. * as the number of available bytes following the end
  492. * of this object.
  493. * \param type ASN type of the object.
  494. * \param string Pointer to the value. If NULL, the octet string will
  495. * be filled with zeros.
  496. * \param strlength Number of bytes in the string value.
  497. *
  498. * \return A pointer to the first byte past the end of this object
  499. * (i.e. the start of the next object). Returns NULL on any
  500. * error.
  501. */
  502. uint8_t *AsnOctetStringBuild(uint8_t * data, size_t * datalength, uint8_t type, const uint8_t * string, size_t strlength)
  503. {
  504. if ((data = AsnHeaderBuild(data, datalength, type, strlength)) == NULL) {
  505. return NULL;
  506. }
  507. if (strlength) {
  508. /* Check for overflow. */
  509. if (*datalength < strlength) {
  510. return NULL;
  511. }
  512. *datalength -= strlength;
  513. if (string) {
  514. memcpy(data, string, strlength);
  515. } else {
  516. memset(data, 0, strlength);
  517. }
  518. data += strlength;
  519. }
  520. return data;
  521. }
  522. /*!
  523. * \brief Pulls an object identifier out of an ASN object ID type.
  524. *
  525. * \param data Pointer to start of the object.
  526. * \param datalength Contains the number of valid bytes following the
  527. * start of the object. On exit, it is returned as
  528. * the number of valid bytes following the end of
  529. * this object.
  530. * \param type Pointer to the variable that receives the ASN type
  531. * of the object.
  532. * \param objid Pointer to the variable that receives the object
  533. * identifier.
  534. * \param objidlength Points to a variable that contains the size of the
  535. * output buffer on entry. On exit, it is returned as
  536. * the number of sub IDs stored in the output buffer.
  537. *
  538. * \return Pointer to the first byte past the end of this object
  539. * (i.e. the start of the next object). Returns NULL on any
  540. * error.
  541. */
  542. const uint8_t *AsnOidParse(const uint8_t * data, size_t * datalength, uint8_t * type, OID * objid, size_t * objidlength)
  543. {
  544. const uint8_t *bufp = data;
  545. OID *oidp = objid + 1;
  546. uint32_t subidentifier;
  547. long length;
  548. uint32_t asn_length;
  549. /* Get type and length. */
  550. *type = *bufp++;
  551. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  552. return NULL;
  553. }
  554. /* Check for overflow and update number of remaining bytes. */
  555. if (asn_length + (bufp - data) > *datalength) {
  556. /* Message overflow. */
  557. return NULL;
  558. }
  559. *datalength -= (int) asn_length + (bufp - data);
  560. /* Handle invalid object ID encodings of the form 06 00 robustly. */
  561. if (asn_length == 0) {
  562. objid[0] = objid[1] = 0;
  563. }
  564. length = asn_length;
  565. /* Account for expansion of first byte. */
  566. (*objidlength)--;
  567. while (length > 0 && (*objidlength)-- > 0) {
  568. subidentifier = 0;
  569. /*
  570. * Shift and add in low order 7 bits.
  571. * Last byte has high bit clear.
  572. */
  573. do {
  574. subidentifier = (subidentifier << 7) + (*(uint8_t *) bufp & ~ASN_BIT8);
  575. length--;
  576. } while (*bufp++ & ASN_BIT8);
  577. *oidp++ = (OID) subidentifier;
  578. }
  579. /*
  580. * The first two subidentifiers are encoded into the first component
  581. * with the value (X * 40) + Y, where
  582. *
  583. * X is the value of the first subidentifier.
  584. * Y is the value of the second subidentifier.
  585. */
  586. subidentifier = objid[1];
  587. if (subidentifier == 0x2B) {
  588. objid[0] = 1;
  589. objid[1] = 3;
  590. } else {
  591. objid[1] = (uint8_t) (subidentifier % 40);
  592. objid[0] = (uint8_t) ((subidentifier - objid[1]) / 40);
  593. }
  594. *objidlength = oidp - objid;
  595. return bufp;
  596. }
  597. /*!
  598. * \brief Build an ASN object identifier.
  599. *
  600. * \param data Pointer to start of the object.
  601. * \param datalength Contains the number of available bytes following
  602. * the start of the object. On exit, it is returned
  603. * as the number of available bytes following the end
  604. * of this object.
  605. * \param type ASN type of the object.
  606. * \param objid Pointer to the object identifier.
  607. * \param objidlength Number of sub IDs in the object identifier.
  608. *
  609. * \return Pointer to the first byte past the end of this object
  610. * (i.e. the start of the next object). Returns NULL on any
  611. * error.
  612. */
  613. uint8_t *AsnOidBuild(uint8_t * data, size_t * datalength, uint8_t type, const OID * objid, size_t objidlength)
  614. {
  615. uint8_t *buf;
  616. uint32_t objid_val;
  617. uint32_t first_objid_val;
  618. size_t asnlength;
  619. const OID *op = objid;
  620. size_t i;
  621. if (objidlength == 0) {
  622. first_objid_val = 0;
  623. objidlength++;
  624. } else if (objid[0] > 2) {
  625. /* First sub identifier is bad. */
  626. return NULL;
  627. } else if (objidlength == 1) {
  628. first_objid_val = op[0] * 40;
  629. } else if (op[1] > 40 && op[0] < 2) {
  630. /* Second sub identifier is bad. */
  631. return NULL;
  632. } else if (objidlength > MAX_OID_LEN) {
  633. /* Bad object ID length. */
  634. return NULL;
  635. } else {
  636. first_objid_val = op[0] * 40 + op[1];
  637. objidlength--;
  638. }
  639. /*
  640. * Determine the number of bytes needed to store the encoded value.
  641. */
  642. if ((buf = malloc(MAX_OID_LEN * sizeof(OID))) == NULL) {
  643. return NULL;
  644. }
  645. asnlength = 0;
  646. for (i = 0; i < objidlength; i++) {
  647. if (i) {
  648. objid_val = *op++;
  649. } else {
  650. objid_val = first_objid_val;
  651. op = objid + 2;
  652. }
  653. if (objid_val < 0x80UL) {
  654. buf[i] = 1;
  655. asnlength += 1;
  656. } else if (objid_val < 0x4000UL) {
  657. buf[i] = 2;
  658. asnlength += 2;
  659. } else if (objid_val < 0x200000UL) {
  660. buf[i] = 3;
  661. asnlength += 3;
  662. } else if (objid_val < 0x10000000UL) {
  663. buf[i] = 4;
  664. asnlength += 4;
  665. } else {
  666. buf[i] = 5;
  667. asnlength += 5;
  668. }
  669. }
  670. /* Build the header after knowing the length. */
  671. if ((data = AsnHeaderBuild(data, datalength, type, asnlength)) == NULL || asnlength > *datalength) {
  672. free(buf);
  673. return NULL;
  674. }
  675. /*
  676. * Store the encoded OID value
  677. */
  678. for (i = 0; i < objidlength; i++) {
  679. if (i) {
  680. objid_val = *op++;
  681. } else {
  682. objid_val = first_objid_val;
  683. op = objid + 2;
  684. }
  685. switch (buf[i]) {
  686. case 1:
  687. *data++ = (uint8_t) objid_val;
  688. break;
  689. case 2:
  690. *data++ = (uint8_t) ((objid_val >> 7) | 0x80);
  691. *data++ = (uint8_t) (objid_val & 0x07f);
  692. break;
  693. case 3:
  694. *data++ = (uint8_t) ((objid_val >> 14) | 0x80);
  695. *data++ = (uint8_t) ((objid_val >> 7 & 0x7f) | 0x80);
  696. *data++ = (uint8_t) (objid_val & 0x07f);
  697. break;
  698. case 4:
  699. *data++ = (uint8_t) ((objid_val >> 21) | 0x80);
  700. *data++ = (uint8_t) ((objid_val >> 14 & 0x7f) | 0x80);
  701. *data++ = (uint8_t) ((objid_val >> 7 & 0x7f) | 0x80);
  702. *data++ = (uint8_t) (objid_val & 0x07f);
  703. break;
  704. case 5:
  705. *data++ = (uint8_t) ((objid_val >> 28) | 0x80);
  706. *data++ = (uint8_t) ((objid_val >> 21 & 0x7f) | 0x80);
  707. *data++ = (uint8_t) ((objid_val >> 14 & 0x7f) | 0x80);
  708. *data++ = (uint8_t) ((objid_val >> 7 & 0x7f) | 0x80);
  709. *data++ = (uint8_t) (objid_val & 0x07f);
  710. break;
  711. }
  712. }
  713. *datalength -= asnlength;
  714. free(buf);
  715. return data;
  716. }
  717. /*!
  718. * \brief Parse an ASN null type.
  719. *
  720. * \param data Pointer to start of the object.
  721. * \param datalength Contains the number of valid bytes following the
  722. * start of the object. On exit, it is returned as
  723. * the number of valid bytes following the end of
  724. * this object.
  725. * \param type Pointer to the variable that receives the ASN type
  726. * of the object.
  727. *
  728. * \return Pointer to the first byte past the end of this object
  729. * (i.e. the start of the next object). Returns NULL on any
  730. * error.
  731. */
  732. const uint8_t *AsnNullParse(const uint8_t * data, size_t * datalength, uint8_t * type)
  733. {
  734. const uint8_t *bufp = data;
  735. uint32_t asn_length;
  736. *type = *bufp++;
  737. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  738. return NULL;
  739. }
  740. if (asn_length) {
  741. return NULL;
  742. }
  743. *datalength -= (bufp - data);
  744. return bufp;
  745. }
  746. /*!
  747. * \brief Build an ASN null object.
  748. *
  749. * \param data Pointer to start of the object.
  750. * \param datalength Contains the number of available bytes following
  751. * the start of the object. On exit, it is returned
  752. * as the number of available bytes following the end
  753. * of this object.
  754. * \param type ASN type of the object.
  755. *
  756. * \return Pointer to the first byte past the end of this object
  757. * (i.e. the start of the next object). Returns NULL on any
  758. * error.
  759. */
  760. uint8_t *AsnNullBuild(uint8_t * data, size_t * datalength, uint8_t type)
  761. {
  762. return AsnHeaderBuild(data, datalength, type, 0);
  763. }
  764. /*!
  765. * \brief Pull a bitstring out of an ASN bitstring type.
  766. *
  767. * \param data Pointer to start of the object.
  768. * \param datalength Contains the number of valid bytes following the
  769. * start of the object. On exit, it is returned as
  770. * the number of valid bytes following the end of
  771. * this object.
  772. * \param type Pointer to the variable that receives the ASN type
  773. * of the object.
  774. * \param string Pointer to the variable that receives the value
  775. * of the object.
  776. * \param strlength Contains the size of the string buffer on entry.
  777. * On exit, it is returned as the number of bytes
  778. * stored in the string buffer.
  779. *
  780. * \return Pointer to the first byte past the end of this object
  781. * (i.e. the start of the next object). Returns NULL on any
  782. * error.
  783. */
  784. const uint8_t *AsnBitStringParse(const uint8_t * data, size_t * datalength, uint8_t * type, uint8_t * string, size_t * strlength)
  785. {
  786. const uint8_t *bufp = data;
  787. uint32_t asn_length;
  788. *type = *bufp++;
  789. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  790. return NULL;
  791. }
  792. if (asn_length + (bufp - data) > *datalength) {
  793. return NULL;
  794. }
  795. if (asn_length < 1 || (size_t) asn_length > *strlength) {
  796. return NULL;
  797. }
  798. if (*bufp > 7) {
  799. return NULL;
  800. }
  801. memcpy(string, bufp, asn_length);
  802. *strlength = (size_t) asn_length;
  803. *datalength -= (size_t) asn_length + (bufp - data);
  804. return bufp + asn_length;
  805. }
  806. /*!
  807. * \brief Build an ASN bit string.
  808. *
  809. * \param data Pointer to start of output buffer
  810. * \param datalength Contains the number of available bytes following
  811. * the start of the object. On exit, it is returned
  812. * as the number of available bytes following the end
  813. * of this object.
  814. * \param type ASN type of the object.
  815. * \param string Pointer to the value. If NULL, the octet string will
  816. * be filled with zeros.
  817. * \param strlength Number of bytes in the string value.
  818. *
  819. * \return A pointer to the first byte past the end of this object
  820. * (i.e. the start of the next object). Returns NULL on any
  821. * error.
  822. */
  823. uint8_t *AsnBitStringBuild(uint8_t * data, size_t * datalength, uint8_t type, const uint8_t * string, size_t strlength)
  824. {
  825. if ((data = AsnHeaderBuild(data, datalength, type, strlength)) == NULL) {
  826. return NULL;
  827. }
  828. if (strlength) {
  829. if (strlength > *datalength) {
  830. return NULL;
  831. }
  832. memcpy((char *) data, (char *) string, strlength);
  833. *datalength -= strlength;
  834. data += strlength;
  835. }
  836. return data;
  837. }
  838. /*!
  839. * \brief Pull a 64 bit unsigned long out of an ASN integer type.
  840. *
  841. * \param data Pointer to start of the object.
  842. * \param datalength Contains the number of valid bytes following the
  843. * start of the object. On exit, it is returned as
  844. * the number of valid bytes following the end of
  845. * this object.
  846. * \param type Pointer to the variable that receives the ASN type
  847. * of the object.
  848. * \param intp Pointer to the variable that receives the value
  849. * of the object.
  850. *
  851. * \return Pointer to the first byte past the end of this object
  852. * (i.e. the start of the next object). Returns NULL on any
  853. * error.
  854. */
  855. const uint8_t *AsnUnsigned64Parse(const uint8_t * data, size_t * datalength, uint8_t * type, UNSIGNED64 * cp)
  856. {
  857. const uint8_t *bufp = data;
  858. uint32_t asn_length;
  859. uint32_t low = 0;
  860. uint32_t high = 0;
  861. size_t intsize = 4;
  862. *type = *bufp++;
  863. if ((bufp = AsnLenParse(bufp, &asn_length)) == NULL) {
  864. return NULL;
  865. }
  866. if (asn_length + (bufp - data) > *datalength) {
  867. return NULL;
  868. }
  869. if ((asn_length > (intsize * 2 + 1)) || ((asn_length == (intsize * 2) + 1) && *bufp != 0x00)) {
  870. return NULL;
  871. }
  872. *datalength -= (int) asn_length + (bufp - data);
  873. if (*bufp & 0x80) {
  874. low = (uint32_t) - 1;
  875. high = (uint32_t) - 1;
  876. }
  877. while (asn_length--) {
  878. high = (high << 8) | ((low & 0xFF000000) >> 24);
  879. low = (low << 8) | *bufp++;
  880. }
  881. cp->low = low;
  882. cp->high = high;
  883. return bufp;
  884. }
  885. /*!
  886. * \brief Build an ASN object containing a 64 bit unsigned integer.
  887. *
  888. * \param data Pointer to start of output buffer
  889. * \param datalength Contains the number of available bytes following
  890. * the start of the object. On exit, it is returned
  891. * as the number of available bytes following the end
  892. * of this object.
  893. * \param type ASN type of the object.
  894. * \param intp Value of the object.
  895. *
  896. * \return A pointer to the first byte past the end of this object
  897. * (i.e. the start of the next object). Returns NULL on any
  898. * error.
  899. */
  900. uint8_t *AsnUnsigned64Build(uint8_t * data, size_t * datalength, uint8_t type, const UNSIGNED64 * cp)
  901. {
  902. uint32_t low;
  903. uint32_t high;
  904. uint32_t mask;
  905. uint32_t mask2;
  906. int add_null_byte = 0;
  907. size_t intsize;
  908. intsize = 8;
  909. low = cp->low;
  910. high = cp->high;
  911. mask = 0xFFUL << (8 * (sizeof(long) - 1));
  912. /*
  913. * mask is 0xFF000000 on a big-endian machine
  914. */
  915. if ((uint8_t) ((high & mask) >> (8 * (sizeof(long) - 1))) & 0x80) {
  916. /* if MSB is set */
  917. add_null_byte = 1;
  918. intsize++;
  919. }
  920. /*
  921. * Truncate "unnecessary" bytes off of the most significant end of
  922. * this 2's complement integer.
  923. * There should be no sequence of 9 consecutive 1's or 0's at the most
  924. * significant end of the integer.
  925. */
  926. mask2 = 0x1FFUL << ((8 * (sizeof(long) - 1)) - 1);
  927. /*
  928. * mask2 is 0xFF800000 on a big-endian machine
  929. */
  930. while ((((high & mask2) == 0) || ((high & mask2) == mask2))
  931. && intsize > 1) {
  932. intsize--;
  933. high = (high << 8)
  934. | ((low & mask) >> (8 * (sizeof(long) - 1)));
  935. low <<= 8;
  936. }
  937. data = AsnHeaderBuild(data, datalength, type, intsize);
  938. if (data == NULL || *datalength < intsize) {
  939. return NULL;
  940. }
  941. *datalength -= intsize;
  942. if (add_null_byte == 1) {
  943. *data++ = '\0';
  944. intsize--;
  945. }
  946. while (intsize--) {
  947. *data++ = (uint8_t) ((high & mask) >> (8 * (sizeof(long) - 1)));
  948. high = (high << 8)
  949. | ((low & mask) >> (8 * (sizeof(long) - 1)));
  950. low <<= 8;
  951. }
  952. return data;
  953. }