Skip to content

Commit

Permalink
fix: update code
Browse files Browse the repository at this point in the history
Signed-off-by: Junjie Gao <junjiegao@microsoft.com>
  • Loading branch information
JeyJeyGao committed Jul 31, 2023
1 parent b3de155 commit 45480e5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 33 deletions.
24 changes: 9 additions & 15 deletions internal/encoding/asn1/asn1.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,36 +42,36 @@ func ConvertToDER(ber []byte) ([]byte, error) {
}

// decode decodes BER-encoded ASN.1 data structures.
func decode(r ReadOnlySlice) (value, error) {
func decode(r readOnlySlice) (value, error) {
identifier, isPrimitiveValue, err := identifierValue(r)
if err != nil {
return nil, err
}
expectedLength, err := decodeLength(r)
contentLength, err := decodeLength(r)
if err != nil {
return nil, err
}
content, err := r.Slice(r.Offset(), r.Offset()+expectedLength)
content, err := r.Slice(r.Offset(), r.Offset()+contentLength)
if err != nil {
return nil, err
}
if err = r.Seek(r.Offset() + expectedLength); err != nil {
if err = r.Seek(r.Offset() + contentLength); err != nil {
return nil, err
}

if isPrimitiveValue {
return newPrimitiveValue(identifier, content)
return newPrimitiveValue(identifier, content), nil
}
return newConstructedValue(identifier, expectedLength, content)
return newConstructedValue(identifier, content)
}

// identifierValue decodes identifierValue octets.
func identifierValue(r ReadOnlySlice) (ReadOnlySlice, bool, error) {
func identifierValue(r readOnlySlice) (readOnlySlice, bool, error) {
b, err := r.ReadByte()
if err != nil {
return nil, false, err
}
isPrimitiveValue := isPrimitive(b)
isPrimitive := b&0x20 == 0

tagBytesCount := 1
// high-tag-number form
Expand All @@ -92,13 +92,7 @@ func identifierValue(r ReadOnlySlice) (ReadOnlySlice, bool, error) {
if err != nil {
return nil, false, err
}
return identifier, isPrimitiveValue, nil
}

// isPrimitive checks the primitive flag in the identifier.
// Returns true if the value is primitive.
func isPrimitive(identifier byte) bool {
return identifier&0x20 == 0
return identifier, isPrimitive, nil
}

// decodeLength decodes length octets.
Expand Down
4 changes: 2 additions & 2 deletions internal/encoding/asn1/constructed.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package asn1

// constructedValue represents a value in constructed encoding.
type constructedValue struct {
identifier ReadOnlySlice
identifier readOnlySlice
length int
members []value
}

// newConstructedValue builds the constructed value.
func newConstructedValue(identifier ReadOnlySlice, expectedLength int, content ReadOnlySlice) (value, error) {
func newConstructedValue(identifier readOnlySlice, content readOnlySlice) (value, error) {
var members []value
encodedLength := 0
for content.Offset() < content.Length() {
Expand Down
8 changes: 4 additions & 4 deletions internal/encoding/asn1/primitive.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package asn1

// primitiveValue represents a value in primitive encoding.
type primitiveValue struct {
identifier ReadOnlySlice
content ReadOnlySlice
identifier readOnlySlice
content readOnlySlice
}

// newPrimitiveValue builds the primitive value.
func newPrimitiveValue(identifier ReadOnlySlice, content ReadOnlySlice) (value, error) {
func newPrimitiveValue(identifier readOnlySlice, content readOnlySlice) value {
return primitiveValue{
identifier: identifier,
content: content,
}, nil
}
}

// Encode encodes the primitive value to the value writer in DER.
Expand Down
43 changes: 31 additions & 12 deletions internal/encoding/asn1/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,42 @@ package asn1

import "io"

type ReadOnlySlice interface {
// readOnlySlice is an interface that represents a read-only slice of bytes.
type readOnlySlice interface {
io.ByteReader
io.Reader

// Length returns the length of the slice.
Length() int

// Offset returns the current offset of the slice.
Offset() int

// Seek sets the current offset of the slice to the given value.
Seek(offset int) error
Slice(begin int, end int) (ReadOnlySlice, error)

// Slice returns a new ReadOnlySlice that represents a sub-slice of the current slice.
// The sub-slice starts at the given begin index and ends at the given end index (exclusive).
Slice(begin int, end int) (readOnlySlice, error)
}

type readOnlySlice struct {
// byteSlice is a struct that implements the ReadOnlySlice interface.
type byteSlice struct {
data []byte
offset int
}

func newReadOnlySlice(data []byte) ReadOnlySlice {
return &readOnlySlice{
// newReadOnlySlice creates a new ReadOnlySlice from the given byte slice.
func newReadOnlySlice(data []byte) readOnlySlice {
return &byteSlice{
data: data,
offset: 0,
}
}

func (r *readOnlySlice) ReadByte() (byte, error) {
// ReadByte reads and returns a single byte from the slice.
// If the end of the slice has been reached, it returns an error.
func (r *byteSlice) ReadByte() (byte, error) {
if r.offset >= len(r.data) {
return 0, ErrEarlyEOF
}
Expand All @@ -32,7 +46,8 @@ func (r *readOnlySlice) ReadByte() (byte, error) {
return b, nil
}

func (r *readOnlySlice) Read(p []byte) (int, error) {
// Read reads up to len(p) bytes from the slice into p.
func (r *byteSlice) Read(p []byte) (int, error) {
if r.offset >= len(r.data) {
return 0, io.EOF
}
Expand All @@ -41,27 +56,31 @@ func (r *readOnlySlice) Read(p []byte) (int, error) {
return n, nil
}

func (r *readOnlySlice) Length() int {
// Length returns the length of the slice.
func (r *byteSlice) Length() int {
return len(r.data)
}

func (r *readOnlySlice) Offset() int {
// Offset returns the current offset of the slice.
func (r *byteSlice) Offset() int {
return r.offset
}

func (r *readOnlySlice) Seek(offset int) error {
// Seek sets the current offset of the slice to the given value.
func (r *byteSlice) Seek(offset int) error {
if offset < 0 || offset > len(r.data) {
return ErrInvalidOffset
}
r.offset = offset
return nil
}

func (r *readOnlySlice) Slice(begin int, end int) (ReadOnlySlice, error) {
// Slice returns a new ReadOnlySlice that represents a sub-slice of the current slice.
func (r *byteSlice) Slice(begin int, end int) (readOnlySlice, error) {
if begin < 0 || end < 0 || begin > end || end > len(r.data) {
return nil, ErrInvalidSlice
}
return &readOnlySlice{
return &byteSlice{
data: r.data[begin:end],
offset: 0,
}, nil
Expand Down

0 comments on commit 45480e5

Please sign in to comment.