Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion ber.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,24 @@ func encodeLength(out *bytes.Buffer, length int) (err error) {
func readObject(ber []byte, offset int) (asn1Object, int, error) {
//fmt.Printf("\n====> Starting readObject at offset: %d\n\n", offset)
tagStart := offset
if offset >= len(ber) {
return nil, 0, errors.New("ber2der: not enough bytes to read tag")
}
b := ber[offset]
offset++

tag := b & 0x1F // last 5 bits
if tag == 0x1F {
tag = 0
if offset >= len(ber) {
return nil, 0, errors.New("ber2der: not enough bytes to read tag")
}
for ber[offset] >= 0x80 {
tag = tag*128 + ber[offset] - 0x80
offset++
if offset >= len(ber) {
return nil, 0, errors.New("ber2der: not enough bytes to read tag")
}
}
tag = tag*128 + ber[offset] - 0x80
offset++
Expand All @@ -159,10 +169,17 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
*/
// read length
var length int
if offset >= len(ber) {
return nil, 0, errors.New("ber2der: not enough bytes to read length")
}
l := ber[offset]
offset++
indefinite := false
if l > 0x80 {
if offset >= len(ber) {
return nil, 0, errors.New("ber2der: not enough bytes to read length")
}

numberOfBytes := (int)(l & 0x7F)
if numberOfBytes > 4 { // int is only guaranteed to be 32bit
return nil, 0, errors.New("ber2der: BER tag length too long")
Expand All @@ -173,6 +190,9 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
if 0x0 == (int)(ber[offset]) {
return nil, 0, errors.New("ber2der: BER tag length has leading zero")
}
if offset+numberOfBytes > len(ber) {
return nil, 0, errors.New("ber2der: not enough bytes to read length")
}
//fmt.Printf("--> (compute length) indicator byte: %x\n", l)
//fmt.Printf("--> (compute length) length bytes: % X\n", ber[offset:offset+numberOfBytes])
for i := 0; i < numberOfBytes; i++ {
Expand Down Expand Up @@ -240,7 +260,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
}

func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
if len(ber) - offset < 2 {
if len(ber)-offset < 2 {
return false, errors.New("ber2der: Invalid BER format")
}

Expand Down
9 changes: 8 additions & 1 deletion ber_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,18 @@ func TestBer2Der_Negatives(t *testing.T) {
Input []byte
ErrorContains string
}{
{[]byte{0x30, 0x85}, "length too long"},
{[]byte{0x30, 0x85}, "not enough"},
{[]byte{0x30, 0x85, 0x00}, "length too long"},
{[]byte{0x30, 0x84, 0x80, 0x0, 0x0, 0x0}, "length is negative"},
{[]byte{0x30, 0x82, 0x0, 0x1}, "length has leading zero"},
{[]byte{0x30, 0x80, 0x1, 0x2, 0x1, 0x2}, "Invalid BER format"},
{[]byte{0x30, 0x03, 0x01, 0x02}, "length is more than available data"},
{[]byte{0x1f}, "not enough bytes to read tag"},
{[]byte{0x1f, 0x80, 0x81, 0xff}, "not enough bytes to read tag"},
{[]byte{0x1f, 0x00}, "not enough bytes to read length"},
{[]byte{0x1f, 0x00, 0xf0}, "not enough bytes to read length"},
{[]byte{0x1f, 0x00, 0x83}, "not enough bytes to read length"},
{[]byte{0x1f, 0x00, 0x83, 0xff}, "not enough bytes to read length"},
}

for _, fixture := range fixtures {
Expand Down