test-asn1.c 4.3 KB

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