LCOV - code coverage report
Current view: top level - lib/util/tests - asn1_tests.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 95 98 96.9 %
Date: 2024-04-21 15:09:00 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    util_asn1 testing
       5             : 
       6             :    Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
       7             :    Copyright (C) Volker Lendecke 2004
       8             :    Copyright (C) Andrew Bartlett 2011
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "torture/torture.h"
      26             : #include "torture/local/proto.h"
      27             : #include "../asn1.h"
      28             : 
      29             : struct oid_data {
      30             :         const char *oid;        /* String OID */
      31             :         const char *bin_oid;    /* Binary OID represented as string */
      32             : };
      33             : 
      34             : /* Data for successful OIDs conversions */
      35             : static const struct oid_data oid_data_ok[] = {
      36             :         {
      37             :                 .oid = "2.5.4.0",
      38             :                 .bin_oid = "550400"
      39             :         },
      40             :         {
      41             :                 .oid = "2.5.4.1",
      42             :                 .bin_oid = "550401"
      43             :         },
      44             :         {
      45             :                 .oid = "2.5.4.130",
      46             :                 .bin_oid = "55048102"
      47             :         },
      48             :         {
      49             :                 .oid = "2.5.130.4",
      50             :                 .bin_oid = "55810204"
      51             :         },
      52             :         {
      53             :                 .oid = "2.5.4.16387",
      54             :                 .bin_oid = "5504818003"
      55             :         },
      56             :         {
      57             :                 .oid = "2.5.16387.4",
      58             :                 .bin_oid = "5581800304"
      59             :         },
      60             :         {
      61             :                 .oid = "2.5.2097155.4",
      62             :                 .bin_oid = "558180800304"
      63             :         },
      64             :         {
      65             :                 .oid = "2.5.4.130.16387.2097155.268435459",
      66             :                 .bin_oid = "55048102818003818080038180808003"
      67             :         },
      68             : };
      69             : 
      70             : /* Data for successful OIDs conversions */
      71             : static const char *oid_data_err[] = {
      72             :                 "",           /* empty OID */
      73             :                 ".2.5.4.130", /* first sub-identifier is empty */
      74             :                 "2.5.4.130.", /* last sub-identifier is empty */
      75             :                 "2..5.4.130", /* second sub-identifier is empty */
      76             :                 "2.5..4.130", /* third sub-identifier is empty */
      77             :                 "2.abc.4.130",        /* invalid sub-identifier */
      78             :                 "2.5abc.4.130", /* invalid sub-identifier (alphanumeric)*/
      79             : };
      80             : 
      81             : /* Data for successful Partial OIDs conversions */
      82             : static const struct oid_data partial_oid_data_ok[] = {
      83             :         {
      84             :                 .oid = "2.5.4.130:0x81",
      85             :                 .bin_oid = "5504810281"
      86             :         },
      87             :         {
      88             :                 .oid = "2.5.4.16387:0x8180",
      89             :                 .bin_oid = "55048180038180"
      90             :         },
      91             :         {
      92             :                 .oid = "2.5.4.16387:0x81",
      93             :                 .bin_oid = "550481800381"
      94             :         },
      95             :         {
      96             :                 .oid = "2.5.2097155.4:0x818080",
      97             :                 .bin_oid = "558180800304818080"
      98             :         },
      99             :         {
     100             :                 .oid = "2.5.2097155.4:0x8180",
     101             :                 .bin_oid = "5581808003048180"
     102             :         },
     103             :         {
     104             :                 .oid = "2.5.2097155.4:0x81",
     105             :                 .bin_oid = "55818080030481"
     106             :         },
     107             : };
     108             : 
     109             : static const struct {
     110             :         DATA_BLOB blob;
     111             :         int value;
     112             : } integer_tests[] = {
     113             :         {
     114             :                 .blob = { discard_const_p(uint8_t, "\x02\x01\x00"), 3},
     115             :                 .value = 0
     116             :         },
     117             :         {
     118             :                 .blob = { discard_const_p(uint8_t, "\x02\x01\x7f"), 3},
     119             :                 .value = 127
     120             :         },
     121             :         {
     122             :                 .blob = { discard_const_p(uint8_t, "\x02\x02\x00\x80"), 4},
     123             :                 .value = 128
     124             :         },
     125             :         {
     126             :                 .blob = { discard_const_p(uint8_t, "\x02\x02\x01\x00"), 4},
     127             :                 .value = 256
     128             :         },
     129             :         {
     130             :                 .blob = { discard_const_p(uint8_t, "\x02\x01\x80"), 3},
     131             :                 .value = -128
     132             :         },
     133             :         {
     134             :                 .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x7f"), 4},
     135             :                 .value = -129
     136             :         },
     137             :         {
     138             :                 .blob = { discard_const_p(uint8_t, "\x02\x01\xff"), 3},
     139             :                 .value = -1
     140             :         },
     141             :         {
     142             :                 .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x01"), 4},
     143             :                 .value = -255
     144             :         },
     145             :         {
     146             :                 .blob = { discard_const_p(uint8_t, "\x02\x02\x00\xff"), 4},
     147             :                 .value = 255
     148             :         },
     149             :         {
     150             :                 .blob = { discard_const_p(uint8_t, "\x02\x04\x80\x00\x00\x00"), 6},
     151             :                 .value = 0x80000000
     152             :         },
     153             :         {
     154             :                 .blob = { discard_const_p(uint8_t, "\x02\x04\x7f\xff\xff\xff"), 6},
     155             :                 .value = 0x7fffffff
     156             :         }
     157             : };
     158             : 
     159             : /* Testing ber_write_OID_String() function */
     160           1 : static bool test_ber_write_OID_String(struct torture_context *tctx)
     161             : {
     162           1 :         int i;
     163           1 :         char *hex_str;
     164           1 :         DATA_BLOB blob;
     165           1 :         TALLOC_CTX *mem_ctx;
     166           1 :         const struct oid_data *data = oid_data_ok;
     167             : 
     168           1 :         mem_ctx = talloc_new(tctx);
     169             : 
     170             :         /* check for valid OIDs */
     171          10 :         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
     172           8 :                 torture_assert(tctx, ber_write_OID_String(mem_ctx, &blob, data[i].oid),
     173             :                                 "ber_write_OID_String failed");
     174             : 
     175           8 :                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
     176           8 :                 torture_assert(tctx, hex_str, "No memory!");
     177             : 
     178           8 :                 torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
     179             :                                 talloc_asprintf(mem_ctx,
     180             :                                                 "Failed: oid=%s, bin_oid:%s",
     181             :                                                 data[i].oid, data[i].bin_oid));
     182             :         }
     183             : 
     184             :         /* check for invalid OIDs */
     185           8 :         for (i = 0; i < ARRAY_SIZE(oid_data_err); i++) {
     186           7 :                 torture_assert(tctx,
     187             :                                !ber_write_OID_String(mem_ctx, &blob, oid_data_err[i]),
     188             :                                talloc_asprintf(mem_ctx,
     189             :                                                "Should fail for [%s] -> %s",
     190             :                                                oid_data_err[i],
     191             :                                                hex_encode_talloc(mem_ctx, blob.data, blob.length)));
     192             :         }
     193             : 
     194           1 :         talloc_free(mem_ctx);
     195             : 
     196           1 :         return true;
     197             : }
     198             : 
     199             : /* Testing ber_read_OID_String() function */
     200           1 : static bool test_ber_read_OID_String(struct torture_context *tctx)
     201             : {
     202           1 :         int i;
     203           1 :         char *oid;
     204           1 :         DATA_BLOB oid_blob;
     205           1 :         TALLOC_CTX *mem_ctx;
     206           1 :         const struct oid_data *data = oid_data_ok;
     207             : 
     208           1 :         mem_ctx = talloc_new(tctx);
     209             : 
     210          10 :         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
     211           8 :                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
     212             : 
     213           8 :                 torture_assert(tctx, ber_read_OID_String(mem_ctx, oid_blob, &oid),
     214             :                                 "ber_read_OID_String failed");
     215             : 
     216           8 :                 torture_assert(tctx, strequal(data[i].oid, oid),
     217             :                                 talloc_asprintf(mem_ctx,
     218             :                                                 "Failed: oid=%s, bin_oid:%s",
     219             :                                                 data[i].oid, data[i].bin_oid));
     220             :         }
     221             : 
     222           1 :         talloc_free(mem_ctx);
     223             : 
     224           1 :         return true;
     225             : }
     226             : 
     227             : /* Testing ber_write_partial_OID_String() function */
     228           1 : static bool test_ber_write_partial_OID_String(struct torture_context *tctx)
     229             : {
     230           1 :         int i;
     231           1 :         char *hex_str;
     232           1 :         DATA_BLOB blob;
     233           1 :         TALLOC_CTX *mem_ctx;
     234           1 :         const struct oid_data *data = oid_data_ok;
     235             : 
     236           1 :         mem_ctx = talloc_new(tctx);
     237             : 
     238             :         /* ber_write_partial_OID_String() should work with not partial OIDs also */
     239          10 :         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
     240           8 :                 torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
     241             :                                 "ber_write_partial_OID_String failed");
     242             : 
     243           8 :                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
     244           8 :                 torture_assert(tctx, hex_str, "No memory!");
     245             : 
     246           8 :                 torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
     247             :                                 talloc_asprintf(mem_ctx,
     248             :                                                 "Failed: oid=%s, bin_oid:%s",
     249             :                                                 data[i].oid, data[i].bin_oid));
     250             :         }
     251             : 
     252             :         /* ber_write_partial_OID_String() test with partial OIDs */
     253           7 :         data = partial_oid_data_ok;
     254           7 :         for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
     255           6 :                 torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
     256             :                                 "ber_write_partial_OID_String failed");
     257             : 
     258           6 :                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
     259           6 :                 torture_assert(tctx, hex_str, "No memory!");
     260             : 
     261           6 :                 torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
     262             :                                 talloc_asprintf(mem_ctx,
     263             :                                                 "Failed: oid=%s, bin_oid:%s",
     264             :                                                 data[i].oid, data[i].bin_oid));
     265             :         }
     266             : 
     267           1 :         talloc_free(mem_ctx);
     268             : 
     269           1 :         return true;
     270             : }
     271             : 
     272             : /* Testing ber_read_partial_OID_String() function */
     273           1 : static bool test_ber_read_partial_OID_String(struct torture_context *tctx)
     274             : {
     275           1 :         int i;
     276           1 :         char *oid;
     277           1 :         DATA_BLOB oid_blob;
     278           1 :         TALLOC_CTX *mem_ctx;
     279           1 :         const struct oid_data *data = oid_data_ok;
     280             : 
     281           1 :         mem_ctx = talloc_new(tctx);
     282             : 
     283             :         /* ber_read_partial_OID_String() should work with not partial OIDs also */
     284          10 :         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
     285           8 :                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
     286             : 
     287           8 :                 torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
     288             :                                 "ber_read_partial_OID_String failed");
     289             : 
     290           8 :                 torture_assert(tctx, strequal(data[i].oid, oid),
     291             :                                 talloc_asprintf(mem_ctx,
     292             :                                                 "Failed: oid=%s, bin_oid:%s",
     293             :                                                 data[i].oid, data[i].bin_oid));
     294             :         }
     295             : 
     296             :         /* ber_read_partial_OID_String() test with partial OIDs */
     297           7 :         data = partial_oid_data_ok;
     298           7 :         for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
     299           6 :                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
     300             : 
     301           6 :                 torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
     302             :                                 "ber_read_partial_OID_String failed");
     303             : 
     304           6 :                 torture_assert(tctx, strequal(data[i].oid, oid),
     305             :                                 talloc_asprintf(mem_ctx,
     306             :                                                 "Failed: oid=%s, bin_oid:%s",
     307             :                                                 data[i].oid, data[i].bin_oid));
     308             :         }
     309             : 
     310           1 :         talloc_free(mem_ctx);
     311             : 
     312           1 :         return true;
     313             : }
     314             : 
     315             : /*
     316             :  * Testing asn1_read_Integer and asn1_write_Integer functions,
     317             :  * inspired by Love Hornquist Astrand
     318             :  */
     319             : 
     320           1 : static bool test_asn1_Integer(struct torture_context *tctx)
     321             : {
     322           1 :         int i;
     323           1 :         TALLOC_CTX *mem_ctx;
     324           1 :         bool ret = false;
     325             : 
     326           1 :         mem_ctx = talloc_new(tctx);
     327             : 
     328          13 :         for (i = 0; i < ARRAY_SIZE(integer_tests); i++) {
     329          11 :                 ASN1_DATA *data;
     330          11 :                 DATA_BLOB blob;
     331          11 :                 int val;
     332             : 
     333          11 :                 data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
     334          11 :                 if (!data) {
     335           0 :                         goto err;
     336             :                 }
     337             : 
     338          11 :                 if (!asn1_write_Integer(data, integer_tests[i].value)) goto err;
     339             : 
     340          11 :                 if (!asn1_blob(data, &blob)) {
     341           0 :                         goto err;
     342             :                 }
     343             : 
     344          11 :                 torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
     345             : 
     346          11 :                 if (!asn1_load(data, blob)) goto err;
     347          11 :                 torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
     348             : 
     349          11 :                 torture_assert_int_equal(tctx, val, integer_tests[i].value,
     350             :                         "readback of asn1_write_Integer output by asn1_read_Integer() failed");
     351             :         }
     352             : 
     353           0 :         ret = true;
     354             : 
     355           1 :   err:
     356             : 
     357           1 :         talloc_free(mem_ctx);
     358           1 :         return ret;
     359             : }
     360             : 
     361             : 
     362             : /* LOCAL-ASN1 test suite creation */
     363        2354 : struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx)
     364             : {
     365        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "asn1");
     366             : 
     367        2354 :         torture_suite_add_simple_test(suite, "ber_write_OID_String",
     368             :                                       test_ber_write_OID_String);
     369             : 
     370        2354 :         torture_suite_add_simple_test(suite, "ber_read_OID_String",
     371             :                                       test_ber_read_OID_String);
     372             : 
     373        2354 :         torture_suite_add_simple_test(suite, "ber_write_partial_OID_String",
     374             :                                       test_ber_write_partial_OID_String);
     375             : 
     376        2354 :         torture_suite_add_simple_test(suite, "ber_read_partial_OID_String",
     377             :                                       test_ber_read_partial_OID_String);
     378             : 
     379        2354 :         torture_suite_add_simple_test(suite, "asn1_Integer",
     380             :                                       test_asn1_Integer);
     381             : 
     382        2354 :         return suite;
     383             : }

Generated by: LCOV version 1.14