diff --git a/ber.go b/ber.go index 5233321..bb785ff 100644 --- a/ber.go +++ b/ber.go @@ -220,14 +220,6 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) { } else { var subObjects []asn1Object for (offset < contentEnd) || indefinite { - var subObj asn1Object - var err error - subObj, offset, err = readObject(ber, offset) - if err != nil { - return nil, 0, err - } - subObjects = append(subObjects, subObj) - if indefinite { terminated, err := isIndefiniteTermination(ber, offset) if err != nil { @@ -238,6 +230,14 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) { break } } + + var subObj asn1Object + var err error + subObj, offset, err = readObject(ber, offset) + if err != nil { + return nil, 0, err + } + subObjects = append(subObjects, subObj) } obj = asn1Structured{ tagBytes: ber[tagStart:tagEnd], diff --git a/ber_test.go b/ber_test.go index f2ba5d2..9cbf9b8 100644 --- a/ber_test.go +++ b/ber_test.go @@ -39,6 +39,35 @@ func TestBer2Der(t *testing.T) { } } +func TestBer2Der_EmptyIndefinite(t *testing.T) { + // indefinite length fixture without content (actual 0-length) + ber := []byte{0x30, 0x80, 0x00, 0x00} + expected := []byte{0x30, 0x00} + der, err := ber2der(ber) + if err != nil { + t.Fatalf("ber2der failed with error: %v", err) + } + if !bytes.Equal(der, expected) { + t.Errorf("ber2der result did not match.\n\tExpected: % X\n\tActual: % X", expected, der) + } + + if der2, err := ber2der(der); err != nil { + t.Errorf("ber2der on DER bytes failed with error: %v", err) + } else { + if !bytes.Equal(der, der2) { + t.Error("ber2der is not idempotent") + } + } + var thing struct { + } + rest, err := asn1.Unmarshal(der, &thing) + if err != nil { + t.Errorf("Cannot parse resulting DER because: %v", err) + } else if len(rest) > 0 { + t.Errorf("Resulting DER has trailing data: % X", rest) + } +} + func TestBer2Der_Negatives(t *testing.T) { fixtures := []struct { Input []byte