github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/x/crypto/cryptobyte/cryptobyte_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cryptobyte 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "testing" 12 ) 13 14 func builderBytesEq(b *Builder, want ...byte) error { 15 got := b.BytesOrPanic() 16 if !bytes.Equal(got, want) { 17 return fmt.Errorf("Bytes() = %v, want %v", got, want) 18 } 19 return nil 20 } 21 22 func TestContinuationError(t *testing.T) { 23 const errorStr = "TestContinuationError" 24 var b Builder 25 b.AddUint8LengthPrefixed(func(b *Builder) { 26 b.AddUint8(1) 27 panic(BuildError{Err: errors.New(errorStr)}) 28 }) 29 30 ret, err := b.Bytes() 31 if ret != nil { 32 t.Error("expected nil result") 33 } 34 if err == nil { 35 t.Fatal("unexpected nil error") 36 } 37 if s := err.Error(); s != errorStr { 38 t.Errorf("expected error %q, got %v", errorStr, s) 39 } 40 } 41 42 func TestContinuationNonError(t *testing.T) { 43 defer func() { 44 recover() 45 }() 46 47 var b Builder 48 b.AddUint8LengthPrefixed(func(b *Builder) { 49 b.AddUint8(1) 50 panic(1) 51 }) 52 53 t.Error("Builder did not panic") 54 } 55 56 func TestGeneratedPanic(t *testing.T) { 57 defer func() { 58 recover() 59 }() 60 61 var b Builder 62 b.AddUint8LengthPrefixed(func(b *Builder) { 63 var p *byte 64 *p = 0 65 }) 66 67 t.Error("Builder did not panic") 68 } 69 70 func TestBytes(t *testing.T) { 71 var b Builder 72 v := []byte("foobarbaz") 73 b.AddBytes(v[0:3]) 74 b.AddBytes(v[3:4]) 75 b.AddBytes(v[4:9]) 76 if err := builderBytesEq(&b, v...); err != nil { 77 t.Error(err) 78 } 79 s := String(b.BytesOrPanic()) 80 for _, w := range []string{"foo", "bar", "baz"} { 81 var got []byte 82 if !s.ReadBytes(&got, 3) { 83 t.Errorf("ReadBytes() = false, want true (w = %v)", w) 84 } 85 want := []byte(w) 86 if !bytes.Equal(got, want) { 87 t.Errorf("ReadBytes(): got = %v, want %v", got, want) 88 } 89 } 90 if len(s) != 0 { 91 t.Errorf("len(s) = %d, want 0", len(s)) 92 } 93 } 94 95 func TestUint8(t *testing.T) { 96 var b Builder 97 b.AddUint8(42) 98 if err := builderBytesEq(&b, 42); err != nil { 99 t.Error(err) 100 } 101 102 var s String = b.BytesOrPanic() 103 var v uint8 104 if !s.ReadUint8(&v) { 105 t.Error("ReadUint8() = false, want true") 106 } 107 if v != 42 { 108 t.Errorf("v = %d, want 42", v) 109 } 110 if len(s) != 0 { 111 t.Errorf("len(s) = %d, want 0", len(s)) 112 } 113 } 114 115 func TestUint16(t *testing.T) { 116 var b Builder 117 b.AddUint16(65534) 118 if err := builderBytesEq(&b, 255, 254); err != nil { 119 t.Error(err) 120 } 121 var s String = b.BytesOrPanic() 122 var v uint16 123 if !s.ReadUint16(&v) { 124 t.Error("ReadUint16() == false, want true") 125 } 126 if v != 65534 { 127 t.Errorf("v = %d, want 65534", v) 128 } 129 if len(s) != 0 { 130 t.Errorf("len(s) = %d, want 0", len(s)) 131 } 132 } 133 134 func TestUint24(t *testing.T) { 135 var b Builder 136 b.AddUint24(0xfffefd) 137 if err := builderBytesEq(&b, 255, 254, 253); err != nil { 138 t.Error(err) 139 } 140 141 var s String = b.BytesOrPanic() 142 var v uint32 143 if !s.ReadUint24(&v) { 144 t.Error("ReadUint8() = false, want true") 145 } 146 if v != 0xfffefd { 147 t.Errorf("v = %d, want fffefd", v) 148 } 149 if len(s) != 0 { 150 t.Errorf("len(s) = %d, want 0", len(s)) 151 } 152 } 153 154 func TestUint24Truncation(t *testing.T) { 155 var b Builder 156 b.AddUint24(0x10111213) 157 if err := builderBytesEq(&b, 0x11, 0x12, 0x13); err != nil { 158 t.Error(err) 159 } 160 } 161 162 func TestUint32(t *testing.T) { 163 var b Builder 164 b.AddUint32(0xfffefdfc) 165 if err := builderBytesEq(&b, 255, 254, 253, 252); err != nil { 166 t.Error(err) 167 } 168 169 var s String = b.BytesOrPanic() 170 var v uint32 171 if !s.ReadUint32(&v) { 172 t.Error("ReadUint8() = false, want true") 173 } 174 if v != 0xfffefdfc { 175 t.Errorf("v = %x, want fffefdfc", v) 176 } 177 if len(s) != 0 { 178 t.Errorf("len(s) = %d, want 0", len(s)) 179 } 180 } 181 182 func TestUMultiple(t *testing.T) { 183 var b Builder 184 b.AddUint8(23) 185 b.AddUint32(0xfffefdfc) 186 b.AddUint16(42) 187 if err := builderBytesEq(&b, 23, 255, 254, 253, 252, 0, 42); err != nil { 188 t.Error(err) 189 } 190 191 var s String = b.BytesOrPanic() 192 var ( 193 x uint8 194 y uint32 195 z uint16 196 ) 197 if !s.ReadUint8(&x) || !s.ReadUint32(&y) || !s.ReadUint16(&z) { 198 t.Error("ReadUint8() = false, want true") 199 } 200 if x != 23 || y != 0xfffefdfc || z != 42 { 201 t.Errorf("x, y, z = %d, %d, %d; want 23, 4294901244, 5", x, y, z) 202 } 203 if len(s) != 0 { 204 t.Errorf("len(s) = %d, want 0", len(s)) 205 } 206 } 207 208 func TestUint8LengthPrefixedSimple(t *testing.T) { 209 var b Builder 210 b.AddUint8LengthPrefixed(func(c *Builder) { 211 c.AddUint8(23) 212 c.AddUint8(42) 213 }) 214 if err := builderBytesEq(&b, 2, 23, 42); err != nil { 215 t.Error(err) 216 } 217 218 var base, child String = b.BytesOrPanic(), nil 219 var x, y uint8 220 if !base.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || 221 !child.ReadUint8(&y) { 222 t.Error("parsing failed") 223 } 224 if x != 23 || y != 42 { 225 t.Errorf("want x, y == 23, 42; got %d, %d", x, y) 226 } 227 if len(base) != 0 { 228 t.Errorf("len(base) = %d, want 0", len(base)) 229 } 230 if len(child) != 0 { 231 t.Errorf("len(child) = %d, want 0", len(child)) 232 } 233 } 234 235 func TestUint8LengthPrefixedMulti(t *testing.T) { 236 var b Builder 237 b.AddUint8LengthPrefixed(func(c *Builder) { 238 c.AddUint8(23) 239 c.AddUint8(42) 240 }) 241 b.AddUint8(5) 242 b.AddUint8LengthPrefixed(func(c *Builder) { 243 c.AddUint8(123) 244 c.AddUint8(234) 245 }) 246 if err := builderBytesEq(&b, 2, 23, 42, 5, 2, 123, 234); err != nil { 247 t.Error(err) 248 } 249 250 var s, child String = b.BytesOrPanic(), nil 251 var u, v, w, x, y uint8 252 if !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&u) || !child.ReadUint8(&v) || 253 !s.ReadUint8(&w) || !s.ReadUint8LengthPrefixed(&child) || !child.ReadUint8(&x) || !child.ReadUint8(&y) { 254 t.Error("parsing failed") 255 } 256 if u != 23 || v != 42 || w != 5 || x != 123 || y != 234 { 257 t.Errorf("u, v, w, x, y = %d, %d, %d, %d, %d; want 23, 42, 5, 123, 234", 258 u, v, w, x, y) 259 } 260 if len(s) != 0 { 261 t.Errorf("len(s) = %d, want 0", len(s)) 262 } 263 if len(child) != 0 { 264 t.Errorf("len(child) = %d, want 0", len(child)) 265 } 266 } 267 268 func TestUint8LengthPrefixedNested(t *testing.T) { 269 var b Builder 270 b.AddUint8LengthPrefixed(func(c *Builder) { 271 c.AddUint8(5) 272 c.AddUint8LengthPrefixed(func(d *Builder) { 273 d.AddUint8(23) 274 d.AddUint8(42) 275 }) 276 c.AddUint8(123) 277 }) 278 if err := builderBytesEq(&b, 5, 5, 2, 23, 42, 123); err != nil { 279 t.Error(err) 280 } 281 282 var base, child1, child2 String = b.BytesOrPanic(), nil, nil 283 var u, v, w, x uint8 284 if !base.ReadUint8LengthPrefixed(&child1) { 285 t.Error("parsing base failed") 286 } 287 if !child1.ReadUint8(&u) || !child1.ReadUint8LengthPrefixed(&child2) || !child1.ReadUint8(&x) { 288 t.Error("parsing child1 failed") 289 } 290 if !child2.ReadUint8(&v) || !child2.ReadUint8(&w) { 291 t.Error("parsing child2 failed") 292 } 293 if u != 5 || v != 23 || w != 42 || x != 123 { 294 t.Errorf("u, v, w, x = %d, %d, %d, %d, want 5, 23, 42, 123", 295 u, v, w, x) 296 } 297 if len(base) != 0 { 298 t.Errorf("len(base) = %d, want 0", len(base)) 299 } 300 if len(child1) != 0 { 301 t.Errorf("len(child1) = %d, want 0", len(child1)) 302 } 303 if len(base) != 0 { 304 t.Errorf("len(child2) = %d, want 0", len(child2)) 305 } 306 } 307 308 func TestPreallocatedBuffer(t *testing.T) { 309 var buf [5]byte 310 b := NewBuilder(buf[0:0]) 311 b.AddUint8(1) 312 b.AddUint8LengthPrefixed(func(c *Builder) { 313 c.AddUint8(3) 314 c.AddUint8(4) 315 }) 316 b.AddUint16(1286) // Outgrow buf by one byte. 317 want := []byte{1, 2, 3, 4, 0} 318 if !bytes.Equal(buf[:], want) { 319 t.Errorf("buf = %v want %v", buf, want) 320 } 321 if err := builderBytesEq(b, 1, 2, 3, 4, 5, 6); err != nil { 322 t.Error(err) 323 } 324 } 325 326 func TestWriteWithPendingChild(t *testing.T) { 327 var b Builder 328 b.AddUint8LengthPrefixed(func(c *Builder) { 329 c.AddUint8LengthPrefixed(func(d *Builder) { 330 defer func() { 331 if recover() == nil { 332 t.Errorf("recover() = nil, want error; c.AddUint8() did not panic") 333 } 334 }() 335 c.AddUint8(2) // panics 336 337 defer func() { 338 if recover() == nil { 339 t.Errorf("recover() = nil, want error; b.AddUint8() did not panic") 340 } 341 }() 342 b.AddUint8(2) // panics 343 }) 344 345 defer func() { 346 if recover() == nil { 347 t.Errorf("recover() = nil, want error; b.AddUint8() did not panic") 348 } 349 }() 350 b.AddUint8(2) // panics 351 }) 352 } 353 354 // ASN.1 355 356 func TestASN1Int64(t *testing.T) { 357 tests := []struct { 358 in int64 359 want []byte 360 }{ 361 {-0x800000, []byte{2, 3, 128, 0, 0}}, 362 {-256, []byte{2, 2, 255, 0}}, 363 {-129, []byte{2, 2, 255, 127}}, 364 {-128, []byte{2, 1, 128}}, 365 {-1, []byte{2, 1, 255}}, 366 {0, []byte{2, 1, 0}}, 367 {1, []byte{2, 1, 1}}, 368 {2, []byte{2, 1, 2}}, 369 {127, []byte{2, 1, 127}}, 370 {128, []byte{2, 2, 0, 128}}, 371 {256, []byte{2, 2, 1, 0}}, 372 {0x800000, []byte{2, 4, 0, 128, 0, 0}}, 373 } 374 for i, tt := range tests { 375 var b Builder 376 b.AddASN1Int64(tt.in) 377 if err := builderBytesEq(&b, tt.want...); err != nil { 378 t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in) 379 } 380 381 var n int64 382 s := String(b.BytesOrPanic()) 383 ok := s.ReadASN1Integer(&n) 384 if !ok || n != tt.in { 385 t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)", 386 ok, n, tt.in, i) 387 } 388 if len(s) != 0 { 389 t.Errorf("len(s) = %d, want 0", len(s)) 390 } 391 } 392 } 393 394 func TestASN1Uint64(t *testing.T) { 395 tests := []struct { 396 in uint64 397 want []byte 398 }{ 399 {0, []byte{2, 1, 0}}, 400 {1, []byte{2, 1, 1}}, 401 {2, []byte{2, 1, 2}}, 402 {127, []byte{2, 1, 127}}, 403 {128, []byte{2, 2, 0, 128}}, 404 {256, []byte{2, 2, 1, 0}}, 405 {0x800000, []byte{2, 4, 0, 128, 0, 0}}, 406 {0x7fffffffffffffff, []byte{2, 8, 127, 255, 255, 255, 255, 255, 255, 255}}, 407 {0x8000000000000000, []byte{2, 9, 0, 128, 0, 0, 0, 0, 0, 0, 0}}, 408 {0xffffffffffffffff, []byte{2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255}}, 409 } 410 for i, tt := range tests { 411 var b Builder 412 b.AddASN1Uint64(tt.in) 413 if err := builderBytesEq(&b, tt.want...); err != nil { 414 t.Errorf("%v, (i = %d; in = %v)", err, i, tt.in) 415 } 416 417 var n uint64 418 s := String(b.BytesOrPanic()) 419 ok := s.ReadASN1Integer(&n) 420 if !ok || n != tt.in { 421 t.Errorf("s.ReadASN1Integer(&n) = %v, n = %d; want true, n = %d (i = %d)", 422 ok, n, tt.in, i) 423 } 424 if len(s) != 0 { 425 t.Errorf("len(s) = %d, want 0", len(s)) 426 } 427 } 428 }