test-asn1.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Testing tool for ASN.1 routines
  3. * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "tls/asn1.h"
  11. extern int wpa_debug_level;
  12. static const char * asn1_class_str(int class)
  13. {
  14. switch (class) {
  15. case ASN1_CLASS_UNIVERSAL:
  16. return "Universal";
  17. case ASN1_CLASS_APPLICATION:
  18. return "Application";
  19. case ASN1_CLASS_CONTEXT_SPECIFIC:
  20. return "Context-specific";
  21. case ASN1_CLASS_PRIVATE:
  22. return "Private";
  23. default:
  24. return "?";
  25. }
  26. }
  27. int asn1_parse(const u8 *buf, size_t len, int level)
  28. {
  29. const u8 *pos, *prev, *end;
  30. char prefix[10], str[100];
  31. int _level;
  32. struct asn1_hdr hdr;
  33. struct asn1_oid oid;
  34. u8 tmp;
  35. _level = level;
  36. if ((size_t) _level > sizeof(prefix) - 1)
  37. _level = sizeof(prefix) - 1;
  38. memset(prefix, ' ', _level);
  39. prefix[_level] = '\0';
  40. pos = buf;
  41. end = buf + len;
  42. while (pos < end) {
  43. if (asn1_get_next(pos, end - pos, &hdr) < 0)
  44. return -1;
  45. prev = pos;
  46. pos = hdr.payload;
  47. wpa_printf(MSG_MSGDUMP, "ASN.1:%s Class %d(%s) P/C %d(%s) "
  48. "Tag %u Length %u",
  49. prefix, hdr.class, asn1_class_str(hdr.class),
  50. hdr.constructed,
  51. hdr.constructed ? "Constructed" : "Primitive",
  52. hdr.tag, hdr.length);
  53. if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC &&
  54. hdr.constructed) {
  55. if (asn1_parse(pos, hdr.length, level + 1) < 0)
  56. return -1;
  57. pos += hdr.length;
  58. }
  59. if (hdr.class != ASN1_CLASS_UNIVERSAL)
  60. continue;
  61. switch (hdr.tag) {
  62. case ASN1_TAG_EOC:
  63. if (hdr.length) {
  64. wpa_printf(MSG_DEBUG, "ASN.1: Non-zero "
  65. "end-of-contents length (%u)",
  66. hdr.length);
  67. return -1;
  68. }
  69. wpa_printf(MSG_MSGDUMP, "ASN.1:%s EOC", prefix);
  70. break;
  71. case ASN1_TAG_BOOLEAN:
  72. if (hdr.length != 1) {
  73. wpa_printf(MSG_DEBUG, "ASN.1: Unexpected "
  74. "Boolean length (%u)", hdr.length);
  75. return -1;
  76. }
  77. tmp = *pos++;
  78. wpa_printf(MSG_MSGDUMP, "ASN.1:%s Boolean %s",
  79. prefix, tmp ? "TRUE" : "FALSE");
  80. break;
  81. case ASN1_TAG_INTEGER:
  82. wpa_hexdump(MSG_MSGDUMP, "ASN.1: INTEGER",
  83. pos, hdr.length);
  84. pos += hdr.length;
  85. break;
  86. case ASN1_TAG_BITSTRING:
  87. wpa_hexdump(MSG_MSGDUMP, "ASN.1: BitString",
  88. pos, hdr.length);
  89. pos += hdr.length;
  90. break;
  91. case ASN1_TAG_OCTETSTRING:
  92. wpa_hexdump(MSG_MSGDUMP, "ASN.1: OctetString",
  93. pos, hdr.length);
  94. pos += hdr.length;
  95. break;
  96. case ASN1_TAG_NULL:
  97. if (hdr.length) {
  98. wpa_printf(MSG_DEBUG, "ASN.1: Non-zero Null "
  99. "length (%u)", hdr.length);
  100. return -1;
  101. }
  102. wpa_printf(MSG_MSGDUMP, "ASN.1:%s Null", prefix);
  103. break;
  104. case ASN1_TAG_OID:
  105. if (asn1_get_oid(prev, end - prev, &oid, &prev) < 0) {
  106. wpa_printf(MSG_DEBUG, "ASN.1: Invalid OID");
  107. return -1;
  108. }
  109. asn1_oid_to_str(&oid, str, sizeof(str));
  110. wpa_printf(MSG_DEBUG, "ASN.1:%s OID %s", prefix, str);
  111. pos += hdr.length;
  112. break;
  113. case ANS1_TAG_RELATIVE_OID:
  114. wpa_hexdump(MSG_MSGDUMP, "ASN.1: Relative OID",
  115. pos, hdr.length);
  116. pos += hdr.length;
  117. break;
  118. case ASN1_TAG_SEQUENCE:
  119. wpa_printf(MSG_MSGDUMP, "ASN.1:%s SEQUENCE", prefix);
  120. if (asn1_parse(pos, hdr.length, level + 1) < 0)
  121. return -1;
  122. pos += hdr.length;
  123. break;
  124. case ASN1_TAG_SET:
  125. wpa_printf(MSG_MSGDUMP, "ASN.1:%s SET", prefix);
  126. if (asn1_parse(pos, hdr.length, level + 1) < 0)
  127. return -1;
  128. pos += hdr.length;
  129. break;
  130. case ASN1_TAG_PRINTABLESTRING:
  131. wpa_hexdump_ascii(MSG_MSGDUMP,
  132. "ASN.1: PrintableString",
  133. pos, hdr.length);
  134. pos += hdr.length;
  135. break;
  136. case ASN1_TAG_IA5STRING:
  137. wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: IA5String",
  138. pos, hdr.length);
  139. pos += hdr.length;
  140. break;
  141. case ASN1_TAG_UTCTIME:
  142. wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: UTCTIME",
  143. pos, hdr.length);
  144. pos += hdr.length;
  145. break;
  146. case ASN1_TAG_VISIBLESTRING:
  147. wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: VisibleString",
  148. pos, hdr.length);
  149. pos += hdr.length;
  150. break;
  151. default:
  152. wpa_printf(MSG_DEBUG, "ASN.1: Unknown tag %d",
  153. hdr.tag);
  154. return -1;
  155. }
  156. }
  157. return 0;
  158. }
  159. int main(int argc, char *argv[])
  160. {
  161. FILE *f;
  162. u8 buf[3000];
  163. size_t len;
  164. wpa_debug_level = 0;
  165. f = fopen(argv[1], "rb");
  166. if (f == NULL)
  167. return -1;
  168. len = fread(buf, 1, sizeof(buf), f);
  169. fclose(f);
  170. if (asn1_parse(buf, len, 0) < 0)
  171. printf("Failed to parse DER ASN.1\n");
  172. printf("\n\n");
  173. return 0;
  174. }