Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

393 строки
8.4 KiB

  1. /* Copyright (c) 2014, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <openssl/buf.h>
  15. #include <openssl/mem.h>
  16. #include <openssl/bytestring.h>
  17. #include <assert.h>
  18. #include <string.h>
  19. #include "internal.h"
  20. void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
  21. cbs->data = data;
  22. cbs->len = len;
  23. }
  24. static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
  25. if (cbs->len < n) {
  26. return 0;
  27. }
  28. *p = cbs->data;
  29. cbs->data += n;
  30. cbs->len -= n;
  31. return 1;
  32. }
  33. int CBS_skip(CBS *cbs, size_t len) {
  34. const uint8_t *dummy;
  35. return cbs_get(cbs, &dummy, len);
  36. }
  37. const uint8_t *CBS_data(const CBS *cbs) {
  38. return cbs->data;
  39. }
  40. size_t CBS_len(const CBS *cbs) {
  41. return cbs->len;
  42. }
  43. int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
  44. OPENSSL_free(*out_ptr);
  45. *out_ptr = NULL;
  46. *out_len = 0;
  47. if (cbs->len == 0) {
  48. return 1;
  49. }
  50. *out_ptr = BUF_memdup(cbs->data, cbs->len);
  51. if (*out_ptr == NULL) {
  52. return 0;
  53. }
  54. *out_len = cbs->len;
  55. return 1;
  56. }
  57. int CBS_strdup(const CBS *cbs, char **out_ptr) {
  58. if (*out_ptr != NULL) {
  59. OPENSSL_free(*out_ptr);
  60. }
  61. *out_ptr = BUF_strndup((const char*)cbs->data, cbs->len);
  62. return (*out_ptr != NULL);
  63. }
  64. int CBS_contains_zero_byte(const CBS *cbs) {
  65. return memchr(cbs->data, 0, cbs->len) != NULL;
  66. }
  67. int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
  68. if (len != cbs->len) {
  69. return 0;
  70. }
  71. return CRYPTO_memcmp(cbs->data, data, len) == 0;
  72. }
  73. static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) {
  74. uint32_t result = 0;
  75. size_t i;
  76. const uint8_t *data;
  77. if (!cbs_get(cbs, &data, len)) {
  78. return 0;
  79. }
  80. for (i = 0; i < len; i++) {
  81. result <<= 8;
  82. result |= data[i];
  83. }
  84. *out = result;
  85. return 1;
  86. }
  87. int CBS_get_u8(CBS *cbs, uint8_t *out) {
  88. const uint8_t *v;
  89. if (!cbs_get(cbs, &v, 1)) {
  90. return 0;
  91. }
  92. *out = *v;
  93. return 1;
  94. }
  95. int CBS_get_u16(CBS *cbs, uint16_t *out) {
  96. uint32_t v;
  97. if (!cbs_get_u(cbs, &v, 2)) {
  98. return 0;
  99. }
  100. *out = v;
  101. return 1;
  102. }
  103. int CBS_get_u24(CBS *cbs, uint32_t *out) {
  104. return cbs_get_u(cbs, out, 3);
  105. }
  106. int CBS_get_u32(CBS *cbs, uint32_t *out) {
  107. return cbs_get_u(cbs, out, 4);
  108. }
  109. int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
  110. const uint8_t *v;
  111. if (!cbs_get(cbs, &v, len)) {
  112. return 0;
  113. }
  114. CBS_init(out, v, len);
  115. return 1;
  116. }
  117. static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
  118. uint32_t len;
  119. if (!cbs_get_u(cbs, &len, len_len)) {
  120. return 0;
  121. }
  122. return CBS_get_bytes(cbs, out, len);
  123. }
  124. int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
  125. return cbs_get_length_prefixed(cbs, out, 1);
  126. }
  127. int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
  128. return cbs_get_length_prefixed(cbs, out, 2);
  129. }
  130. int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
  131. return cbs_get_length_prefixed(cbs, out, 3);
  132. }
  133. int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
  134. size_t *out_header_len) {
  135. uint8_t tag, length_byte;
  136. CBS header = *cbs;
  137. CBS throwaway;
  138. if (out == NULL) {
  139. out = &throwaway;
  140. }
  141. if (!CBS_get_u8(&header, &tag) ||
  142. !CBS_get_u8(&header, &length_byte)) {
  143. return 0;
  144. }
  145. if ((tag & 0x1f) == 0x1f) {
  146. /* Long form tags are not supported. */
  147. return 0;
  148. }
  149. if (out_tag != NULL) {
  150. *out_tag = tag;
  151. }
  152. size_t len;
  153. if ((length_byte & 0x80) == 0) {
  154. /* Short form length. */
  155. len = ((size_t) length_byte) + 2;
  156. if (out_header_len != NULL) {
  157. *out_header_len = 2;
  158. }
  159. } else {
  160. /* Long form length. */
  161. const size_t num_bytes = length_byte & 0x7f;
  162. uint32_t len32;
  163. if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
  164. /* indefinite length */
  165. *out_header_len = 2;
  166. return CBS_get_bytes(cbs, out, 2);
  167. }
  168. if (num_bytes == 0 || num_bytes > 4) {
  169. return 0;
  170. }
  171. if (!cbs_get_u(&header, &len32, num_bytes)) {
  172. return 0;
  173. }
  174. if (len32 < 128) {
  175. /* Length should have used short-form encoding. */
  176. return 0;
  177. }
  178. if ((len32 >> ((num_bytes-1)*8)) == 0) {
  179. /* Length should have been at least one byte shorter. */
  180. return 0;
  181. }
  182. len = len32;
  183. if (len + 2 + num_bytes < len) {
  184. /* Overflow. */
  185. return 0;
  186. }
  187. len += 2 + num_bytes;
  188. if (out_header_len != NULL) {
  189. *out_header_len = 2 + num_bytes;
  190. }
  191. }
  192. return CBS_get_bytes(cbs, out, len);
  193. }
  194. static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
  195. int skip_header) {
  196. size_t header_len;
  197. unsigned tag;
  198. CBS throwaway;
  199. if (out == NULL) {
  200. out = &throwaway;
  201. }
  202. if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
  203. tag != tag_value ||
  204. (header_len > 0 &&
  205. /* This ensures that the tag is either zero length or
  206. * indefinite-length. */
  207. CBS_len(out) == header_len &&
  208. CBS_data(out)[header_len - 1] == 0x80)) {
  209. return 0;
  210. }
  211. if (skip_header && !CBS_skip(out, header_len)) {
  212. assert(0);
  213. return 0;
  214. }
  215. return 1;
  216. }
  217. int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
  218. return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
  219. }
  220. int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
  221. return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
  222. }
  223. int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
  224. if (CBS_len(cbs) < 1) {
  225. return 0;
  226. }
  227. return CBS_data(cbs)[0] == tag_value;
  228. }
  229. int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
  230. CBS bytes;
  231. const uint8_t *data;
  232. size_t i, len;
  233. if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
  234. return 0;
  235. }
  236. *out = 0;
  237. data = CBS_data(&bytes);
  238. len = CBS_len(&bytes);
  239. if (len == 0) {
  240. /* An INTEGER is encoded with at least one octet. */
  241. return 0;
  242. }
  243. if ((data[0] & 0x80) != 0) {
  244. /* Negative number. */
  245. return 0;
  246. }
  247. if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) {
  248. /* Extra leading zeros. */
  249. return 0;
  250. }
  251. for (i = 0; i < len; i++) {
  252. if ((*out >> 56) != 0) {
  253. /* Too large to represent as a uint64_t. */
  254. return 0;
  255. }
  256. *out <<= 8;
  257. *out |= data[i];
  258. }
  259. return 1;
  260. }
  261. int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
  262. if (CBS_peek_asn1_tag(cbs, tag)) {
  263. if (!CBS_get_asn1(cbs, out, tag)) {
  264. return 0;
  265. }
  266. *out_present = 1;
  267. } else {
  268. *out_present = 0;
  269. }
  270. return 1;
  271. }
  272. int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
  273. unsigned tag) {
  274. CBS child;
  275. int present;
  276. if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
  277. return 0;
  278. }
  279. if (present) {
  280. if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
  281. CBS_len(&child) != 0) {
  282. return 0;
  283. }
  284. } else {
  285. CBS_init(out, NULL, 0);
  286. }
  287. if (out_present) {
  288. *out_present = present;
  289. }
  290. return 1;
  291. }
  292. int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
  293. uint64_t default_value) {
  294. CBS child;
  295. int present;
  296. if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
  297. return 0;
  298. }
  299. if (present) {
  300. if (!CBS_get_asn1_uint64(&child, out) ||
  301. CBS_len(&child) != 0) {
  302. return 0;
  303. }
  304. } else {
  305. *out = default_value;
  306. }
  307. return 1;
  308. }
  309. int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
  310. int default_value) {
  311. CBS child, child2;
  312. int present;
  313. if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
  314. return 0;
  315. }
  316. if (present) {
  317. uint8_t boolean;
  318. if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
  319. CBS_len(&child2) != 1 ||
  320. CBS_len(&child) != 0) {
  321. return 0;
  322. }
  323. boolean = CBS_data(&child2)[0];
  324. if (boolean == 0) {
  325. *out = 0;
  326. } else if (boolean == 0xff) {
  327. *out = 1;
  328. } else {
  329. return 0;
  330. }
  331. } else {
  332. *out = default_value;
  333. }
  334. return 1;
  335. }