asn1.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (c) 2016 Christian Huitema <huitema@huitema.net>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /*
  17. * Basic ASN1 validation and optional print-out
  18. */
  19. #ifdef _WINDOWS
  20. #include "wincompat.h"
  21. #else
  22. #include <sys/time.h>
  23. #endif
  24. #include <errno.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <stdio.h>
  28. #include "picotls.h"
  29. #include "picotls/minicrypto.h"
  30. #include "picotls/asn1.h"
  31. static char const *asn1_type_classes[4] = {"Universal", "Application", "Context-specific", "Private"};
  32. static char const *asn1_universal_types[] = {
  33. "End-of-Content", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL",
  34. "OBJECT IDENTIFIER", "Object Descriptor", "EXTERNAL", "REAL", "ENUMERATED", "EMBEDDED PDV",
  35. "UTF8String", "RELATIVE-OID", "Reserved (16)", "Reserved (17)", "SEQUENCE", "SET",
  36. "NumericString", "PrintableString", "T61String", "VideotexString", "IA5String", "UTCTime",
  37. "GeneralizedTime", "GraphicString", "VisibleString", "GeneralString", "UniversalString", "CHARACTER STRING",
  38. "BMPString"};
  39. static size_t nb_asn1_universal_types = sizeof(asn1_universal_types) / sizeof(char const *);
  40. static void ptls_asn1_print_indent(int level, ptls_minicrypto_log_ctx_t *log_ctx)
  41. {
  42. for (int indent = 0; indent <= level; indent++) {
  43. log_ctx->fn(log_ctx->ctx, " ");
  44. }
  45. }
  46. size_t ptls_asn1_error_message(char const *error_label, size_t bytes_max, size_t byte_index, int level,
  47. ptls_minicrypto_log_ctx_t *log_ctx)
  48. {
  49. if (log_ctx != NULL) {
  50. ptls_asn1_print_indent(level, log_ctx);
  51. log_ctx->fn(log_ctx->ctx, "Error: %s (near position: %d (0x%x) out of %d)", error_label, (int)byte_index,
  52. (uint32_t)byte_index, (int)bytes_max);
  53. }
  54. return byte_index;
  55. }
  56. void ptls_asn1_dump_content(const uint8_t *bytes, size_t bytes_max, size_t byte_index, ptls_minicrypto_log_ctx_t *log_ctx)
  57. {
  58. if (log_ctx != NULL && bytes_max > byte_index) {
  59. size_t nb_bytes = bytes_max - byte_index;
  60. log_ctx->fn(log_ctx->ctx, " ");
  61. for (size_t i = 0; i < 16 && i < nb_bytes; i++) {
  62. log_ctx->fn(log_ctx->ctx, "%02x", bytes[byte_index + i]);
  63. }
  64. if (nb_bytes > 16) {
  65. log_ctx->fn(log_ctx->ctx, "...");
  66. }
  67. }
  68. }
  69. size_t ptls_asn1_read_type(const uint8_t *bytes, size_t bytes_max, int *structure_bit, int *type_class, uint32_t *type_number,
  70. int *decode_error, int level, ptls_minicrypto_log_ctx_t *log_ctx)
  71. {
  72. /* Get the type byte */
  73. size_t byte_index = 1;
  74. uint8_t first_byte = bytes[0];
  75. *structure_bit = (first_byte >> 5) & 1;
  76. *type_class = (first_byte >> 6) & 3;
  77. *type_number = first_byte & 31;
  78. if (*type_number == 31) {
  79. uint32_t long_type = 0;
  80. const uint32_t type_number_limit = 0x07FFFFFFF;
  81. int next_byte;
  82. int end_found = 0;
  83. while (byte_index < bytes_max && long_type <= type_number_limit) {
  84. next_byte = bytes[byte_index++];
  85. long_type <<= 7;
  86. long_type |= next_byte & 127;
  87. if ((next_byte & 128) == 0) {
  88. end_found = 1;
  89. break;
  90. }
  91. }
  92. if (end_found) {
  93. *type_number = long_type;
  94. } else {
  95. /* This is an error */
  96. byte_index = ptls_asn1_error_message("Incorrect type coding", bytes_max, byte_index, level, log_ctx);
  97. *decode_error = PTLS_ERROR_BER_MALFORMED_TYPE;
  98. }
  99. }
  100. return byte_index;
  101. }
  102. void ptls_asn1_print_type(int type_class, uint32_t type_number, int level, ptls_minicrypto_log_ctx_t *log_ctx)
  103. {
  104. /* Print the type */
  105. ptls_asn1_print_indent(level, log_ctx);
  106. if (type_class == 0 && type_number < nb_asn1_universal_types) {
  107. log_ctx->fn(log_ctx->ctx, "%s", asn1_universal_types[type_number]);
  108. } else if (type_class == 2) {
  109. log_ctx->fn(log_ctx->ctx, "[%d]", type_number);
  110. } else {
  111. log_ctx->fn(log_ctx->ctx, "%s[%d]", asn1_type_classes[type_class], type_number);
  112. }
  113. }
  114. size_t ptls_asn1_read_length(const uint8_t *bytes, size_t bytes_max, size_t byte_index, uint32_t *length, int *indefinite_length,
  115. size_t *last_byte, int *decode_error, int level, ptls_minicrypto_log_ctx_t *log_ctx)
  116. {
  117. int length_of_length = 0;
  118. *indefinite_length = 0;
  119. *length = 0;
  120. *last_byte = bytes_max;
  121. if (byte_index < bytes_max) {
  122. *length = bytes[byte_index++];
  123. if ((*length & 128) != 0) {
  124. length_of_length = *length & 127;
  125. *length = 0;
  126. if (byte_index + length_of_length >= bytes_max) {
  127. /* This is an error */
  128. byte_index = ptls_asn1_error_message("Incorrect length coding", bytes_max, byte_index, level, log_ctx);
  129. *decode_error = PTLS_ERROR_BER_MALFORMED_LENGTH;
  130. } else {
  131. for (int i = 0; i < length_of_length && byte_index < bytes_max; i++) {
  132. *length <<= 8;
  133. *length |= bytes[byte_index++];
  134. }
  135. if (length_of_length == 0) {
  136. *last_byte = bytes_max;
  137. *indefinite_length = 1;
  138. } else {
  139. *last_byte = byte_index + *length;
  140. }
  141. }
  142. } else {
  143. *last_byte = byte_index + *length;
  144. }
  145. if (*decode_error == 0) {
  146. /* TODO: verify that the length makes sense */
  147. if (*last_byte > bytes_max) {
  148. byte_index = ptls_asn1_error_message("Length larger than message", bytes_max, byte_index, level, log_ctx);
  149. *decode_error = PTLS_ERROR_BER_EXCESSIVE_LENGTH;
  150. }
  151. }
  152. }
  153. return byte_index;
  154. }
  155. size_t ptls_asn1_get_expected_type_and_length(const uint8_t *bytes, size_t bytes_max, size_t byte_index, uint8_t expected_type,
  156. uint32_t *length, int *indefinite_length, size_t *last_byte, int *decode_error,
  157. ptls_minicrypto_log_ctx_t *log_ctx)
  158. {
  159. int is_indefinite = 0;
  160. /* Check that the expected type is present */
  161. if (bytes[byte_index] != expected_type) {
  162. byte_index = ptls_asn1_error_message("Unexpected type", bytes_max, byte_index, 0, log_ctx);
  163. *decode_error = PTLS_ERROR_INCORRECT_ASN1_SYNTAX;
  164. } else {
  165. /* get length of element */
  166. byte_index++;
  167. byte_index =
  168. ptls_asn1_read_length(bytes, bytes_max, byte_index, length, &is_indefinite, last_byte, decode_error, 0, log_ctx);
  169. if (indefinite_length != NULL) {
  170. *indefinite_length = is_indefinite;
  171. } else if (is_indefinite) {
  172. byte_index = ptls_asn1_error_message("Incorrect length for DER", bytes_max, byte_index, 0, log_ctx);
  173. *decode_error = PTLS_ERROR_DER_INDEFINITE_LENGTH;
  174. }
  175. }
  176. return byte_index;
  177. }
  178. size_t ptls_asn1_validation_recursive(const uint8_t *bytes, size_t bytes_max, int *decode_error, int level,
  179. ptls_minicrypto_log_ctx_t *log_ctx)
  180. {
  181. /* Get the type byte */
  182. int structure_bit = 0;
  183. int type_class = 0;
  184. uint32_t type_number = 0;
  185. uint32_t length = 0;
  186. int indefinite_length = 0;
  187. size_t last_byte = 0;
  188. /* Decode the type */
  189. size_t byte_index =
  190. ptls_asn1_read_type(bytes, bytes_max, &structure_bit, &type_class, &type_number, decode_error, level, log_ctx);
  191. if (*decode_error == 0 && log_ctx != NULL) {
  192. ptls_asn1_print_type(type_class, type_number, level, log_ctx);
  193. }
  194. /* Get the length */
  195. byte_index =
  196. ptls_asn1_read_length(bytes, bytes_max, byte_index, &length, &indefinite_length, &last_byte, decode_error, level, log_ctx);
  197. if (last_byte <= bytes_max) {
  198. if (structure_bit) {
  199. /* If structured, recurse on a loop */
  200. if (log_ctx != NULL) {
  201. log_ctx->fn(log_ctx->ctx, " {\n");
  202. }
  203. while (byte_index < last_byte) {
  204. if (indefinite_length != 0 && bytes[byte_index] == 0) {
  205. if (byte_index + 2 > bytes_max || bytes[byte_index + 1] != 0) {
  206. byte_index =
  207. ptls_asn1_error_message("EOC: unexpected end of content", bytes_max, byte_index, level + 1, log_ctx);
  208. *decode_error = PTLS_ERROR_BER_UNEXPECTED_EOC;
  209. byte_index = bytes_max;
  210. break;
  211. } else {
  212. if (log_ctx != NULL) {
  213. ptls_asn1_print_indent(level, log_ctx);
  214. log_ctx->fn(log_ctx->ctx, "EOC\n");
  215. }
  216. byte_index += 2;
  217. break;
  218. }
  219. } else {
  220. byte_index += ptls_asn1_validation_recursive(bytes + byte_index, last_byte - byte_index, decode_error,
  221. level + 1, log_ctx);
  222. if (*decode_error) {
  223. byte_index = bytes_max;
  224. break;
  225. }
  226. }
  227. if (log_ctx != NULL) {
  228. if (byte_index < last_byte) {
  229. log_ctx->fn(log_ctx->ctx, ",");
  230. }
  231. log_ctx->fn(log_ctx->ctx, "\n");
  232. }
  233. }
  234. if (log_ctx != NULL) {
  235. ptls_asn1_print_indent(level, log_ctx);
  236. log_ctx->fn(log_ctx->ctx, "}");
  237. }
  238. } else {
  239. ptls_asn1_dump_content(bytes, last_byte, byte_index, log_ctx);
  240. byte_index = last_byte;
  241. }
  242. }
  243. return byte_index;
  244. }
  245. int ptls_asn1_validation(const uint8_t *bytes, size_t length, ptls_minicrypto_log_ctx_t *log_ctx)
  246. {
  247. int decode_error = 0;
  248. size_t decoded = ptls_asn1_validation_recursive(bytes, length, &decode_error, 0, log_ctx);
  249. if (decode_error == 0 && decoded < length) {
  250. decode_error = PTLS_ERROR_BER_ELEMENT_TOO_SHORT;
  251. if (log_ctx != NULL) {
  252. log_ctx->fn(log_ctx->ctx, "Type too short, %d bytes only out of %d\n", (int)decoded, (int)length);
  253. }
  254. }
  255. return decode_error;
  256. }