/* Reads and returns the next DER encoded SEQUENCE from r, which may optionally be base64 encoded and may be preceded by "garbage". The returned data will always be DER bytes without preceding garbage and NOT base64 encoded. The SEQUENCE will only be recognized as valid if it does not contain APPLICATION or PRIVATE tags or tags >= 31. This function takes care not to read more bytes than necessary which allows the function to be called multiple times on a stream of concatenated SEQUENCEs. */ func ReadNextSEQUENCE(r io.Reader) ([]byte, error) { b := []byte{0} var err error var n int space := true var eaters deque.Deque for { n, err = r.Read(b) if err != nil { return nil, err } if n == 0 { return nil, io.EOF } if b[0] == 0x30 { // SEQUENCE eaters.Push(newRawEater()) } if b[0] > ' ' { if space { eaters.Push(newBase64Eater()) } space = false } else { space = true } for i := 0; i < eaters.Count(); { result := eaters.At(i).(eater).Eat(b[0]) switch result { case -1: // error eaters.RemoveAt(i) case 0: // ok, need more data i++ case 1: // done return eaters.At(i).(eater).Data(), nil } } } }