Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 1 | #undef NDEBUG |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <sys/types.h> |
| 5 | #include <string.h> |
| 6 | #include <assert.h> |
| 7 | |
| 8 | #include <T.h> |
| 9 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 10 | |
| 11 | uint8_t buf1[] = { |
| 12 | 32 | (2 << 6), /* [0], constructed */ |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 13 | 25, /* L */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 14 | |
| 15 | /* string [0] IMPLICIT UTF8String, */ |
| 16 | (2 << 6), /* [0] */ |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 17 | 16, /* L */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 18 | 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', |
| 19 | |
| 20 | /* beta [2] IMPLICIT INTEGER OPTIONAL */ |
| 21 | (2 << 6) + 2, /* [2] */ |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 22 | 5, /* L */ |
| 23 | 0, |
| 24 | 75, |
| 25 | 0x4b, |
| 26 | 75, |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 27 | 75, |
| 28 | }; |
| 29 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 30 | uint8_t buf1_reconstr[] = { |
| 31 | 32 | (2 << 6), /* [0], constructed */ |
| 32 | 24, /* L */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 33 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 34 | /* string [0] IMPLICIT UTF8String, */ |
| 35 | (2 << 6), /* [0] */ |
| 36 | 16, /* L */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 37 | 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', |
| 38 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 39 | /* beta [2] IMPLICIT INTEGER OPTIONAL */ |
| 40 | (2 << 6) + 2, /* [2] */ |
| 41 | 4, /* L */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 42 | 75, |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 43 | 75, |
| 44 | 75, |
| 45 | 0x4b, |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 46 | }; |
| 47 | |
| 48 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 49 | static void |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 50 | check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) { |
Lev Walkin | 90bf7ae | 2004-10-20 15:46:56 +0000 | [diff] [blame] | 51 | asn_dec_rval_t rval; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 52 | |
| 53 | tp = memset(tp, 0, sizeof(*tp)); |
| 54 | |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 55 | fprintf(stderr, "Buf %p (%zd)\n", buf, size); |
Lev Walkin | c7400c5 | 2004-09-29 13:14:36 +0000 | [diff] [blame] | 56 | rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size); |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 57 | fprintf(stderr, "Returned code %d, consumed %zd\n", |
| 58 | (int)rval.code, rval.consumed); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 59 | |
| 60 | assert(rval.code == RC_OK); |
| 61 | assert(rval.consumed == consumed); |
| 62 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 63 | assert(tp->choice.seq.string.size == 16); |
Lev Walkin | 5b63acf | 2014-01-14 01:48:37 -0800 | [diff] [blame] | 64 | assert(strcmp((char *)tp->choice.seq.string.buf, "zzzzzzzzzzzzzzzz") == 0); |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 65 | assert(tp->choice.seq.alpha == NULL); |
| 66 | assert(tp->choice.seq.beta); |
| 67 | assert(*tp->choice.seq.beta == 0x4b4b4b4b); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 68 | } |
| 69 | |
Lev Walkin | 67c2aec | 2004-06-05 08:47:18 +0000 | [diff] [blame] | 70 | size_t buf_pos; |
| 71 | size_t buf_size; |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 72 | uint8_t *buf; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 73 | |
| 74 | static int |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 75 | buf_fill(const void *buffer, size_t size, void *app_key) { |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 76 | |
Lev Walkin | 67c2aec | 2004-06-05 08:47:18 +0000 | [diff] [blame] | 77 | (void)app_key; /* Unused argument */ |
| 78 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 79 | if(buf_pos + size > buf_size) { |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 80 | fprintf(stderr, "%zd + %zd > %zd\n", |
| 81 | buf_pos, size, buf_size); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 82 | return -1; |
| 83 | } |
| 84 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 85 | memcpy(buf + buf_pos, buffer, size); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 86 | buf_pos += size; |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 87 | fprintf(stderr, " written %zd (%zd)\n", size, buf_pos); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 88 | |
| 89 | return 0; |
| 90 | } |
| 91 | |
Lev Walkin | 6fc5660 | 2004-08-20 13:16:42 +0000 | [diff] [blame] | 92 | static void |
Lev Walkin | bc09dd4 | 2017-10-19 02:16:35 -0700 | [diff] [blame] | 93 | compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) { |
Lev Walkin | a9cc46e | 2004-09-22 16:06:28 +0000 | [diff] [blame] | 94 | asn_enc_rval_t erval; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 95 | |
| 96 | buf_size = cmp_buf_size + 100; |
Lev Walkin | a4f8e94 | 2017-10-08 19:28:20 -0700 | [diff] [blame] | 97 | uint8_t scratch[buf_size]; |
| 98 | buf = scratch; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 99 | buf_pos = 0; |
| 100 | |
| 101 | /* |
| 102 | * Try to re-create using DER encoding. |
| 103 | */ |
Lev Walkin | c7400c5 | 2004-09-29 13:14:36 +0000 | [diff] [blame] | 104 | erval = der_encode(&asn_DEF_T, tp, buf_fill, 0); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 105 | assert(erval.encoded != -1); |
Lev Walkin | bc09dd4 | 2017-10-19 02:16:35 -0700 | [diff] [blame] | 106 | if((size_t)erval.encoded != cmp_buf_size) { |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 107 | printf("%zd != %zd\n", erval.encoded, cmp_buf_size); |
Lev Walkin | bc09dd4 | 2017-10-19 02:16:35 -0700 | [diff] [blame] | 108 | assert((size_t)erval.encoded == cmp_buf_size); |
| 109 | } |
| 110 | for(size_t i = 0; i < cmp_buf_size; i++) { |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 111 | if(buf[i] != cmp_buf[i]) { |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 112 | fprintf(stderr, "Recreated buffer content mismatch:\n"); |
Lev Walkin | bc09dd4 | 2017-10-19 02:16:35 -0700 | [diff] [blame] | 113 | fprintf(stderr, "Byte %zd, %x != %x (%d != %d)\n", |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 114 | i, |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 115 | buf[i], cmp_buf[i], |
| 116 | buf[i], cmp_buf[i] |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 117 | ); |
| 118 | } |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 119 | assert(buf[i] == cmp_buf[i]); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 120 | } |
Lev Walkin | a4f8e94 | 2017-10-08 19:28:20 -0700 | [diff] [blame] | 121 | |
| 122 | buf = 0; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | static void |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 126 | partial_read(uint8_t *buf_0, size_t size) { |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 127 | T_t t, *tp; |
Lev Walkin | 90bf7ae | 2004-10-20 15:46:56 +0000 | [diff] [blame] | 128 | asn_dec_rval_t rval; |
Lev Walkin | a4f8e94 | 2017-10-08 19:28:20 -0700 | [diff] [blame] | 129 | uint8_t buf_1[size]; |
| 130 | uint8_t buf_2[size]; |
| 131 | uint8_t buf_3[size]; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 132 | |
| 133 | fprintf(stderr, "\nPartial read sequence...\n"); |
| 134 | |
| 135 | /* |
| 136 | * Divide the space (size) into three blocks in various combinations: |
| 137 | * |<----->i1<----->i2<----->| |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 138 | * ^ buf_0 ^ buf_0+size |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 139 | * Try to read block by block. |
| 140 | */ |
Lev Walkin | a4f8e94 | 2017-10-08 19:28:20 -0700 | [diff] [blame] | 141 | for(size_t i1 = 0; i1 < size; i1++) { |
| 142 | for(size_t i2 = i1; i2 < size; i2++) { |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 143 | uint8_t *chunk1 = buf_0; |
Lev Walkin | 67c2aec | 2004-06-05 08:47:18 +0000 | [diff] [blame] | 144 | size_t size1 = i1; |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 145 | uint8_t *chunk2 = buf_0 + size1; |
Lev Walkin | 67c2aec | 2004-06-05 08:47:18 +0000 | [diff] [blame] | 146 | size_t size2 = i2 - i1; |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 147 | uint8_t *chunk3 = buf_0 + size1 + size2; |
Lev Walkin | 67c2aec | 2004-06-05 08:47:18 +0000 | [diff] [blame] | 148 | size_t size3 = size - size1 - size2; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 149 | |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 150 | fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n", |
| 151 | size, size1, size2, size3); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 152 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 153 | memset(buf_1, 0, size); |
| 154 | memset(buf_2, 0, size); |
| 155 | memset(buf_3, 0, size); |
| 156 | memcpy(buf_1, chunk1, size1); |
| 157 | memcpy(buf_2, chunk2, size2); |
| 158 | memcpy(buf_3, chunk3, size3); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 159 | |
| 160 | tp = memset(&t, 0, sizeof(t)); |
| 161 | |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 162 | fprintf(stderr, "=> Chunk 1 (%zd):\n", size1); |
Lev Walkin | c7400c5 | 2004-09-29 13:14:36 +0000 | [diff] [blame] | 163 | rval = ber_decode(0, &asn_DEF_T, (void **)&tp, |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 164 | buf_1, size1); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 165 | assert(rval.code == RC_WMORE); |
| 166 | assert(rval.consumed <= size1); |
| 167 | if(rval.consumed < size1) { |
| 168 | int leftover = size1 - rval.consumed; |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 169 | memcpy(buf_2, buf_1 + rval.consumed, leftover); |
| 170 | memcpy(buf_2 + leftover, chunk2, size2); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 171 | size2 += leftover; |
| 172 | } |
| 173 | |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 174 | fprintf(stderr, "=> Chunk 2 (%zd):\n", size2); |
Lev Walkin | c7400c5 | 2004-09-29 13:14:36 +0000 | [diff] [blame] | 175 | rval = ber_decode(0, &asn_DEF_T, (void **)&tp, |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 176 | buf_2, size2); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 177 | assert(rval.code == RC_WMORE); |
| 178 | assert(rval.consumed <= size2); |
| 179 | if(rval.consumed < size2) { |
| 180 | int leftover = size2 - rval.consumed; |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 181 | memcpy(buf_3, buf_2 + rval.consumed, leftover); |
| 182 | memcpy(buf_3 + leftover, chunk3, size3); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 183 | size3 += leftover; |
| 184 | } |
| 185 | |
Lev Walkin | 1715b32 | 2013-03-28 04:02:13 -0700 | [diff] [blame] | 186 | fprintf(stderr, "=> Chunk 3 (%zd):\n", size3); |
Lev Walkin | c7400c5 | 2004-09-29 13:14:36 +0000 | [diff] [blame] | 187 | rval = ber_decode(0, &asn_DEF_T, (void **)&tp, |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 188 | buf_3, size3); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 189 | assert(rval.code == RC_OK); |
| 190 | assert(rval.consumed == size3); |
| 191 | |
Lev Walkin | 8d99d7b | 2017-08-25 01:06:00 -0700 | [diff] [blame] | 192 | ASN_STRUCT_RESET(asn_DEF_T, &t); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 193 | } |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | int |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 198 | main(int ac, char **av) { |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 199 | T_t t; |
| 200 | |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 201 | (void)ac; /* Unused argument */ |
| 202 | (void)av; /* Unused argument */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 203 | |
| 204 | /* Check exact buf1 */ |
| 205 | check(&t, buf1, sizeof(buf1), sizeof(buf1)); |
| 206 | compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 207 | asn_fprint(stderr, &asn_DEF_T, &t); |
Lev Walkin | 8d99d7b | 2017-08-25 01:06:00 -0700 | [diff] [blame] | 208 | ASN_STRUCT_RESET(asn_DEF_T, &t); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 209 | |
| 210 | /* Check slightly more than buf1 */ |
| 211 | check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1)); |
| 212 | compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 213 | asn_fprint(stderr, &asn_DEF_T, &t); |
Lev Walkin | 8d99d7b | 2017-08-25 01:06:00 -0700 | [diff] [blame] | 214 | ASN_STRUCT_RESET(asn_DEF_T, &t); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 215 | |
| 216 | /* Split the buffer in parts and check decoder restartability */ |
Lev Walkin | 2a744a7 | 2013-03-27 01:56:23 -0700 | [diff] [blame] | 217 | partial_read(buf1, sizeof(buf1)); |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 218 | |
| 219 | return 0; |
| 220 | } |