d2i_test.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /* Regression tests for ASN.1 parsing bugs. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "testutil.h"
  13. #include <openssl/asn1.h>
  14. #include <openssl/asn1t.h>
  15. #include <openssl/bio.h>
  16. #include <openssl/err.h>
  17. #include <openssl/x509.h>
  18. #include <openssl/x509v3.h>
  19. #include "internal/nelem.h"
  20. static const ASN1_ITEM *item_type;
  21. static const char *test_file;
  22. typedef enum {
  23. ASN1_UNKNOWN,
  24. ASN1_OK,
  25. ASN1_BIO,
  26. ASN1_DECODE,
  27. ASN1_ENCODE,
  28. ASN1_COMPARE
  29. } expected_error_t;
  30. typedef struct {
  31. const char *str;
  32. expected_error_t code;
  33. } error_enum;
  34. static expected_error_t expected_error = ASN1_UNKNOWN;
  35. static int test_bad_asn1(void)
  36. {
  37. BIO *bio = NULL;
  38. ASN1_VALUE *value = NULL;
  39. int ret = 0;
  40. unsigned char buf[2048];
  41. const unsigned char *buf_ptr = buf;
  42. unsigned char *der = NULL;
  43. int derlen;
  44. int len;
  45. bio = BIO_new_file(test_file, "r");
  46. if (!TEST_ptr(bio))
  47. return 0;
  48. if (expected_error == ASN1_BIO) {
  49. if (TEST_ptr_null(ASN1_item_d2i_bio(item_type, bio, NULL)))
  50. ret = 1;
  51. goto err;
  52. }
  53. /*
  54. * Unless we are testing it we don't use ASN1_item_d2i_bio because it
  55. * performs sanity checks on the input and can reject it before the
  56. * decoder is called.
  57. */
  58. len = BIO_read(bio, buf, sizeof(buf));
  59. if (!TEST_int_ge(len, 0))
  60. goto err;
  61. value = ASN1_item_d2i(NULL, &buf_ptr, len, item_type);
  62. if (value == NULL) {
  63. if (TEST_int_eq(expected_error, ASN1_DECODE))
  64. ret = 1;
  65. goto err;
  66. }
  67. derlen = ASN1_item_i2d(value, &der, item_type);
  68. if (der == NULL || derlen < 0) {
  69. if (TEST_int_eq(expected_error, ASN1_ENCODE))
  70. ret = 1;
  71. goto err;
  72. }
  73. if (derlen != len || memcmp(der, buf, derlen) != 0) {
  74. if (TEST_int_eq(expected_error, ASN1_COMPARE))
  75. ret = 1;
  76. goto err;
  77. }
  78. if (TEST_int_eq(expected_error, ASN1_OK))
  79. ret = 1;
  80. err:
  81. /* Don't indicate success for memory allocation errors */
  82. if (ret == 1
  83. && !TEST_false(ERR_GET_REASON(ERR_peek_error()) == ERR_R_MALLOC_FAILURE))
  84. ret = 0;
  85. BIO_free(bio);
  86. OPENSSL_free(der);
  87. ASN1_item_free(value, item_type);
  88. return ret;
  89. }
  90. OPT_TEST_DECLARE_USAGE("item_name expected_error test_file.der\n")
  91. /*
  92. * Usage: d2i_test <name> <type> <file>, e.g.
  93. * d2i_test generalname bad_generalname.der
  94. */
  95. int setup_tests(void)
  96. {
  97. const char *test_type_name;
  98. const char *expected_error_string;
  99. size_t i;
  100. static error_enum expected_errors[] = {
  101. {"OK", ASN1_OK},
  102. {"BIO", ASN1_BIO},
  103. {"decode", ASN1_DECODE},
  104. {"encode", ASN1_ENCODE},
  105. {"compare", ASN1_COMPARE}
  106. };
  107. if (!TEST_ptr(test_type_name = test_get_argument(0))
  108. || !TEST_ptr(expected_error_string = test_get_argument(1))
  109. || !TEST_ptr(test_file = test_get_argument(2)))
  110. return 0;
  111. item_type = ASN1_ITEM_lookup(test_type_name);
  112. if (item_type == NULL) {
  113. TEST_error("Unknown type %s", test_type_name);
  114. TEST_note("Supported types:");
  115. for (i = 0;; i++) {
  116. const ASN1_ITEM *it = ASN1_ITEM_get(i);
  117. if (it == NULL)
  118. break;
  119. TEST_note("\t%s", it->sname);
  120. }
  121. return 0;
  122. }
  123. for (i = 0; i < OSSL_NELEM(expected_errors); i++) {
  124. if (strcmp(expected_errors[i].str, expected_error_string) == 0) {
  125. expected_error = expected_errors[i].code;
  126. break;
  127. }
  128. }
  129. if (expected_error == ASN1_UNKNOWN) {
  130. TEST_error("Unknown expected error %s\n", expected_error_string);
  131. return 0;
  132. }
  133. ADD_TEST(test_bad_asn1);
  134. return 1;
  135. }