Compare commits
3 Commits
master
...
old-router
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7709efff2b | ||
![]() |
dc9b969bcf | ||
![]() |
575e877115 |
@@ -96,14 +96,39 @@ func (c *Certificate) ExcessBytes() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the entire certificate in []byte form, trims payload to specified length.
|
// Data returns the payload of a Certificate, payload is trimmed to the specified length
|
||||||
|
func (c *Certificate) Data() []byte {
|
||||||
|
length := c.Length()
|
||||||
|
if length == 0 {
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if length > len(c.payload) {
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"specified_length": length,
|
||||||
|
"actual_length": len(c.payload),
|
||||||
|
}).Warn("Certificate payload shorter than specified length")
|
||||||
|
return c.payload
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.payload[:length]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the entire certificate in []byte form
|
||||||
func (c *Certificate) Bytes() []byte {
|
func (c *Certificate) Bytes() []byte {
|
||||||
|
if c.kind.Int() == CERT_NULL {
|
||||||
|
return []byte{0, 0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
bytes := c.kind.Bytes()
|
bytes := c.kind.Bytes()
|
||||||
bytes = append(bytes, c.len.Bytes()...)
|
bytes = append(bytes, c.len.Bytes()...)
|
||||||
bytes = append(bytes, c.Data()...)
|
bytes = append(bytes, c.Data()...)
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"bytes_length": len(bytes),
|
"bytes_length": len(bytes),
|
||||||
|
"cert_type": c.kind.Int(),
|
||||||
}).Debug("Generated bytes for certificate")
|
}).Debug("Generated bytes for certificate")
|
||||||
|
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,21 +155,6 @@ func (c *Certificate) Length() (length int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data returns the payload of a Certificate, payload is trimmed to the specified length.
|
|
||||||
func (c *Certificate) Data() (data []byte) {
|
|
||||||
lastElement := c.Length()
|
|
||||||
if lastElement > len(c.payload) {
|
|
||||||
data = c.payload
|
|
||||||
log.Warn("Certificate payload shorter than specified length")
|
|
||||||
} else {
|
|
||||||
data = c.payload[0:lastElement]
|
|
||||||
}
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"data_length": len(data),
|
|
||||||
}).Debug("Retrieved certificate data")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// readCertificate creates a new Certficiate from []byte
|
// readCertificate creates a new Certficiate from []byte
|
||||||
// returns err if the certificate is too short or if the payload doesn't match specified length.
|
// returns err if the certificate is too short or if the payload doesn't match specified length.
|
||||||
func readCertificate(data []byte) (certificate Certificate, err error) {
|
func readCertificate(data []byte) (certificate Certificate, err error) {
|
||||||
@@ -156,44 +166,67 @@ func readCertificate(data []byte) (certificate Certificate, err error) {
|
|||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"at": "(Certificate) NewCertificate",
|
"at": "(Certificate) NewCertificate",
|
||||||
"certificate_bytes_length": len(data),
|
"certificate_bytes_length": len(data),
|
||||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
"reason": "too short (len < CERT_MIN_SIZE)",
|
||||||
}).Error("invalid certificate, empty")
|
}).Error("invalid certificate, empty")
|
||||||
err = fmt.Errorf("error parsing certificate: certificate is empty")
|
err = fmt.Errorf("error parsing certificate: certificate is empty")
|
||||||
return
|
return
|
||||||
case 1, 2:
|
case 1, 2:
|
||||||
certificate.kind = Integer(data[0 : len(data)-1])
|
certificate.kind = Integer(data[0:1])
|
||||||
certificate.len = Integer([]byte{0})
|
certificate.len = Integer([]byte{0})
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"at": "(Certificate) NewCertificate",
|
"at": "(Certificate) NewCertificate",
|
||||||
"certificate_bytes_length": len(data),
|
"certificate_bytes_length": len(data),
|
||||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
"reason": "too short (len < CERT_MIN_SIZE)",
|
||||||
}).Error("invalid certificate, too short")
|
}).Error("invalid certificate, too short")
|
||||||
err = fmt.Errorf("error parsing certificate: certificate is too short")
|
err = fmt.Errorf("error parsing certificate: certificate is too short")
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
certificate.kind = Integer(data[0:1])
|
certificate.kind = Integer(data[0:1])
|
||||||
certificate.len = Integer(data[1:3])
|
certificate.len = Integer(data[1:3])
|
||||||
payloadLength := len(data) - CERT_MIN_SIZE
|
|
||||||
certificate.payload = data[CERT_MIN_SIZE:]
|
// Validate certificate type
|
||||||
if certificate.len.Int() > len(data)-CERT_MIN_SIZE {
|
if certificate.kind.Int() < CERT_NULL || certificate.kind.Int() > CERT_KEY {
|
||||||
err = fmt.Errorf("certificate parsing warning: certificate data is shorter than specified by length")
|
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"at": "(Certificate) NewCertificate",
|
"at": "(Certificate) NewCertificate",
|
||||||
"certificate_bytes_length": certificate.len.Int(),
|
"type": certificate.kind.Int(),
|
||||||
"certificate_payload_length": payloadLength,
|
}).Error("invalid certificate type")
|
||||||
"data_bytes:": string(data),
|
err = fmt.Errorf("error parsing certificate: invalid type: %d", certificate.kind.Int())
|
||||||
"kind_bytes": data[0:1],
|
|
||||||
"len_bytes": data[1:3],
|
|
||||||
"reason": err.Error(),
|
|
||||||
}).Error("invalid certificate, shorter than specified by length")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"type": certificate.kind.Int(),
|
// Handle NULL certificates
|
||||||
"length": certificate.len.Int(),
|
if certificate.kind.Int() == CERT_NULL && certificate.len.Int() != 0 {
|
||||||
}).Debug("Successfully created new certificate")
|
log.WithFields(logrus.Fields{
|
||||||
return
|
"at": "(Certificate) NewCertificate",
|
||||||
|
"length": certificate.len.Int(),
|
||||||
|
}).Error("NULL certificate must have zero length")
|
||||||
|
err = fmt.Errorf("error parsing certificate: NULL certificate must have zero length")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate payload length
|
||||||
|
expectedLength := certificate.len.Int()
|
||||||
|
actualLength := len(data) - CERT_MIN_SIZE
|
||||||
|
|
||||||
|
if expectedLength > actualLength {
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"at": "(Certificate) NewCertificate",
|
||||||
|
"expected_length": expectedLength,
|
||||||
|
"actual_length": actualLength,
|
||||||
|
}).Error("certificate data shorter than specified length")
|
||||||
|
err = fmt.Errorf("error parsing certificate: data shorter than specified length")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
certificate.payload = data[CERT_MIN_SIZE:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"type": certificate.kind.Int(),
|
||||||
|
"length": certificate.len.Int(),
|
||||||
|
}).Debug("Successfully parsed certificate")
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at the end of the input.
|
// ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at the end of the input.
|
||||||
|
@@ -38,7 +38,8 @@ func (i Date) Bytes() []byte {
|
|||||||
|
|
||||||
// Int returns the Date as a Go integer.
|
// Int returns the Date as a Go integer.
|
||||||
func (i Date) Int() int {
|
func (i Date) Int() int {
|
||||||
return intFromBytes(i.Bytes())
|
val, _ := intFromBytes(i.Bytes())
|
||||||
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time takes the value stored in date as an 8 byte big-endian integer representing the
|
// Time takes the value stored in date as an 8 byte big-endian integer representing the
|
||||||
|
@@ -2,6 +2,8 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"crypto/subtle"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,38 +12,68 @@ import (
|
|||||||
Accurate for version 0.9.49
|
Accurate for version 0.9.49
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Represents the SHA256 of some data.
|
Represents the SHA256 of some data. Used throughout I2P for data verification
|
||||||
|
and identity representation. Must be compared using constant-time operations
|
||||||
|
to prevent timing attacks.
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
32 bytes
|
32 bytes representing a SHA256 hash value
|
||||||
|
|
||||||
[I2P Hash]:
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Hash is the represenation of an I2P Hash.
|
var (
|
||||||
//
|
ErrInvalidHashSize = errors.New("invalid hash size")
|
||||||
|
ErrNilReader = errors.New("nil reader")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hash is the representation of an I2P Hash.
|
||||||
|
// It is always exactly 32 bytes containing a SHA256 sum.
|
||||||
|
//
|
||||||
// https://geti2p.net/spec/common-structures#hash
|
// https://geti2p.net/spec/common-structures#hash
|
||||||
type Hash [32]byte
|
type Hash [32]byte
|
||||||
|
|
||||||
|
// Bytes returns a copy of the Hash as a 32-byte array.
|
||||||
|
// This prevents modification of the original hash value.
|
||||||
func (h Hash) Bytes() [32]byte {
|
func (h Hash) Bytes() [32]byte {
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Equal compares two hashes in constant time.
|
||||||
|
// Returns true if the hashes are identical.
|
||||||
|
func (h Hash) Equal(other Hash) bool {
|
||||||
|
return subtle.ConstantTimeCompare(h[:], other[:]) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsZero returns true if the hash is all zeros.
|
||||||
|
func (h Hash) IsZero() bool {
|
||||||
|
var zero Hash
|
||||||
|
return h.Equal(zero)
|
||||||
|
}
|
||||||
|
|
||||||
// HashData returns the SHA256 sum of a []byte input as Hash.
|
// HashData returns the SHA256 sum of a []byte input as Hash.
|
||||||
func HashData(data []byte) (h Hash) {
|
// Never returns an error as SHA256 operates on any input length.
|
||||||
// log.Println("Hashing Data:", data)
|
func HashData(data []byte) Hash {
|
||||||
h = sha256.Sum256(data)
|
if data == nil {
|
||||||
return
|
data = []byte{} // Handle nil input gracefully
|
||||||
|
}
|
||||||
|
return sha256.Sum256(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashReader returns the SHA256 sum from all data read from an io.Reader.
|
// HashReader returns the SHA256 sum from all data read from an io.Reader.
|
||||||
// return error if one occurs while reading from reader
|
// Returns an error if one occurs while reading from reader or if reader is nil.
|
||||||
func HashReader(r io.Reader) (h Hash, err error) {
|
func HashReader(r io.Reader) (Hash, error) {
|
||||||
sha := sha256.New()
|
var h Hash
|
||||||
_, err = io.Copy(sha, r)
|
|
||||||
if err == nil {
|
if r == nil {
|
||||||
d := sha.Sum(nil)
|
return h, ErrNilReader
|
||||||
copy(h[:], d)
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
sha := sha256.New()
|
||||||
|
_, err := io.Copy(sha, r)
|
||||||
|
if err != nil {
|
||||||
|
return h, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := sha.Sum(nil)
|
||||||
|
copy(h[:], sum)
|
||||||
|
return h, nil
|
||||||
|
}
|
65
lib/common/data/hash_test.go
Normal file
65
lib/common/data/hash_test.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package data
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHash(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
data []byte
|
||||||
|
want Hash
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Empty input",
|
||||||
|
data: []byte{},
|
||||||
|
want: HashData([]byte{}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Nil input",
|
||||||
|
data: nil,
|
||||||
|
want: HashData([]byte{}),
|
||||||
|
},
|
||||||
|
// Add more test cases
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := HashData(tt.data)
|
||||||
|
if !got.Equal(tt.want) {
|
||||||
|
t.Errorf("HashData() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHashReader(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
reader io.Reader
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Nil reader",
|
||||||
|
reader: nil,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty reader",
|
||||||
|
reader: strings.NewReader(""),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
// Add more test cases
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := HashReader(tt.reader)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("HashReader() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -2,13 +2,15 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes.
|
// MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes.
|
||||||
const MAX_INTEGER_SIZE = 8
|
const MAX_INTEGER_SIZE = 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[I2P Hash]
|
[I2P Integer]
|
||||||
Accurate for version 0.9.49
|
Accurate for version 0.9.49
|
||||||
|
|
||||||
Description
|
Description
|
||||||
@@ -18,68 +20,112 @@ Contents
|
|||||||
1 to 8 bytes in network byte order (big endian) representing an unsigned integer.
|
1 to 8 bytes in network byte order (big endian) representing an unsigned integer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Integer is the represenation of an I2P Integer.
|
var (
|
||||||
//
|
// ErrInvalidSize indicates the requested integer size is invalid (<=0 or >MAX_INTEGER_SIZE)
|
||||||
// https://geti2p.net/spec/common-structures#integer
|
ErrInvalidSize = errors.New("invalid integer size")
|
||||||
|
// ErrInsufficientData indicates there isn't enough data to read the requested size
|
||||||
|
ErrInsufficientData = errors.New("insufficient data")
|
||||||
|
// ErrNegativeValue indicates an attempt to create an Integer from a negative value
|
||||||
|
ErrNegativeValue = errors.New("negative values not allowed")
|
||||||
|
// ErrIntegerOverflow indicates the value exceeds the maximum allowed size
|
||||||
|
ErrIntegerOverflow = errors.New("integer overflow")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Integer is the representation of an I2P Integer.
|
||||||
|
// It contains 1 to 8 bytes in network byte order (big endian)
|
||||||
|
// representing an unsigned integer value.
|
||||||
type Integer []byte
|
type Integer []byte
|
||||||
|
|
||||||
// Bytes returns the raw []byte content of an Integer.
|
// Bytes returns the raw []byte content of an Integer.
|
||||||
|
// This represents the big-endian encoded form of the integer.
|
||||||
func (i Integer) Bytes() []byte {
|
func (i Integer) Bytes() []byte {
|
||||||
return i[:]
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the Date as a Go integer
|
// Int returns the Integer as a Go integer.
|
||||||
|
// Returns an error if the value would overflow on the current platform
|
||||||
|
// or if the encoding is invalid.
|
||||||
func (i Integer) Int() int {
|
func (i Integer) Int() int {
|
||||||
return intFromBytes(i.Bytes())
|
val, _ := intFromBytes(i)
|
||||||
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadInteger returns an Integer from a []byte of specified length.
|
// ReadInteger returns an Integer from a []byte of specified length.
|
||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
func ReadInteger(bytes []byte, size int) (Integer, []byte) {
|
// Returns an error if size is invalid or there isn't enough data.
|
||||||
if len(bytes) < size {
|
func ReadInteger(bytes []byte, size int) (Integer, []byte, error) {
|
||||||
return bytes[:size], bytes[len(bytes):]
|
if size <= 0 {
|
||||||
|
return nil, bytes, ErrInvalidSize
|
||||||
}
|
}
|
||||||
return bytes[:size], bytes[size:]
|
if size > len(bytes) {
|
||||||
|
return nil, bytes, ErrInsufficientData
|
||||||
|
}
|
||||||
|
return Integer(bytes[:size]), bytes[size:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInteger creates a new Integer from []byte using ReadInteger.
|
// NewInteger creates a new Integer from []byte using ReadInteger.
|
||||||
// Limits the length of the created Integer to MAX_INTEGER_SIZE.
|
// Limits the length of the created Integer to MAX_INTEGER_SIZE.
|
||||||
// Returns a pointer to Integer unlike ReadInteger.
|
// Returns a pointer to Integer and the remaining bytes.
|
||||||
func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error) {
|
// Returns an error if size is invalid or there isn't enough data.
|
||||||
integerSize := MAX_INTEGER_SIZE
|
func NewInteger(bytes []byte, size int) (*Integer, []byte, error) {
|
||||||
if size < MAX_INTEGER_SIZE {
|
if size <= 0 || size > MAX_INTEGER_SIZE {
|
||||||
integerSize = size
|
return nil, bytes, ErrInvalidSize
|
||||||
}
|
}
|
||||||
intBytes := bytes[:integerSize]
|
if len(bytes) < size {
|
||||||
remainder = bytes[integerSize:]
|
return nil, bytes, ErrInsufficientData
|
||||||
i, _ := ReadInteger(intBytes, integerSize)
|
}
|
||||||
integer = &i
|
|
||||||
return
|
integer, remainder, err := ReadInteger(bytes, size)
|
||||||
|
if err != nil {
|
||||||
|
return nil, bytes, err
|
||||||
|
}
|
||||||
|
return &integer, remainder, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte length.
|
// NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte length.
|
||||||
func NewIntegerFromInt(value int, size int) (integer *Integer, err error) {
|
// The value must be non-negative and fit within the specified number of bytes.
|
||||||
bytes := make([]byte, MAX_INTEGER_SIZE)
|
// Returns an error if the size is invalid or the value cannot be represented.
|
||||||
binary.BigEndian.PutUint64(bytes, uint64(value))
|
func NewIntegerFromInt(value int, size int) (*Integer, error) {
|
||||||
integerSize := MAX_INTEGER_SIZE
|
if size <= 0 || size > MAX_INTEGER_SIZE {
|
||||||
if size < MAX_INTEGER_SIZE {
|
return nil, ErrInvalidSize
|
||||||
integerSize = size
|
|
||||||
}
|
}
|
||||||
objinteger, _, err := NewInteger(bytes[MAX_INTEGER_SIZE-integerSize:], integerSize)
|
if value < 0 {
|
||||||
integer = objinteger
|
return nil, ErrNegativeValue
|
||||||
return
|
}
|
||||||
|
|
||||||
|
// Check if value fits in specified size
|
||||||
|
maxVal := int(math.Pow(2, float64(size*8))) - 1
|
||||||
|
if value > maxVal {
|
||||||
|
return nil, ErrIntegerOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, MAX_INTEGER_SIZE)
|
||||||
|
binary.BigEndian.PutUint64(buf, uint64(value))
|
||||||
|
|
||||||
|
data := buf[MAX_INTEGER_SIZE-size:]
|
||||||
|
integer := Integer(data)
|
||||||
|
return &integer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpret a slice of bytes from length 0 to length 8 as a big-endian
|
// intFromBytes interprets a slice of bytes from length 0 to length 8 as a big-endian
|
||||||
// integer and return an int representation.
|
// integer and returns an int representation.
|
||||||
func intFromBytes(number []byte) (value int) {
|
// Returns an error if the value would overflow on the current platform
|
||||||
num_len := len(number)
|
// or if the input is invalid.
|
||||||
if num_len < MAX_INTEGER_SIZE {
|
func intFromBytes(number []byte) (int, error) {
|
||||||
number = append(
|
if len(number) == 0 {
|
||||||
make([]byte, MAX_INTEGER_SIZE-num_len),
|
return 0, nil
|
||||||
number...,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
value = int(binary.BigEndian.Uint64(number))
|
if len(number) > MAX_INTEGER_SIZE {
|
||||||
return
|
return 0, ErrInvalidSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
padded := make([]byte, MAX_INTEGER_SIZE)
|
||||||
|
copy(padded[MAX_INTEGER_SIZE-len(number):], number)
|
||||||
|
|
||||||
|
val := int64(binary.BigEndian.Uint64(padded))
|
||||||
|
if val > math.MaxInt32 || val < math.MinInt32 {
|
||||||
|
return 0, ErrIntegerOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(val), nil
|
||||||
|
}
|
@@ -30,3 +30,32 @@ func TestIsZeroWithNoData(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(integer.Int(), 0, "Integer() did not correctly parse zero length byte slice")
|
assert.Equal(integer.Int(), 0, "Integer() did not correctly parse zero length byte slice")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIntegerEdgeCases(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input []byte
|
||||||
|
size int
|
||||||
|
wantErr bool
|
||||||
|
wantInt int
|
||||||
|
}{
|
||||||
|
{"empty input", []byte{}, 1, true, 0},
|
||||||
|
{"zero size", []byte{1}, 0, true, 0},
|
||||||
|
{"oversized", []byte{1}, 9, true, 0},
|
||||||
|
{"valid small", []byte{42}, 1, false, 42},
|
||||||
|
{"valid max", []byte{1, 2, 3, 4, 5, 6, 7, 8}, 8, false, 72623859790382856},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
i, _, err := NewInteger(tt.input, tt.size)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("NewInteger() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err == nil && i.Int() != tt.wantInt {
|
||||||
|
t.Errorf("Integer.Int() = %v, want %v", i.Int(), tt.wantInt)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -97,34 +98,20 @@ func (mapping *Mapping) HasDuplicateKeys() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GoMapToMapping converts a Go map of unformatted strings to *Mapping.
|
// GoMapToMapping converts a Go map of unformatted strings to *Mapping.
|
||||||
func GoMapToMapping(gomap map[string]string) (mapping *Mapping, err error) {
|
func GoMapToMapping(gomap map[string]string) (*Mapping, error) {
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"input_map_size": len(gomap),
|
|
||||||
}).Debug("Converting Go map to Mapping")
|
|
||||||
map_vals := MappingValues{}
|
map_vals := MappingValues{}
|
||||||
for k, v := range gomap {
|
for k, v := range gomap {
|
||||||
key_str, kerr := ToI2PString(k)
|
key_str, err := ToI2PString(k)
|
||||||
if kerr != nil {
|
if err != nil {
|
||||||
log.WithError(kerr).Error("Failed to convert key to I2PString")
|
return nil, fmt.Errorf("key conversion error: %w", err)
|
||||||
err = kerr
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
val_str, verr := ToI2PString(v)
|
val_str, err := ToI2PString(v)
|
||||||
if verr != nil {
|
if err != nil {
|
||||||
log.WithError(verr).Error("Failed to convert value to I2PString")
|
return nil, fmt.Errorf("value conversion error: %w", err)
|
||||||
err = verr
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
map_vals = append(
|
map_vals = append(map_vals, [2]I2PString{key_str, val_str})
|
||||||
map_vals,
|
|
||||||
[2]I2PString{key_str, val_str},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
mapping = ValuesToMapping(map_vals)
|
return ValuesToMapping(map_vals), nil
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"mapping_size": len(map_vals),
|
|
||||||
}).Debug("Successfully converted Go map to Mapping")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the string parsing error indicates that the Mapping
|
// Check if the string parsing error indicates that the Mapping
|
||||||
@@ -152,10 +139,37 @@ func beginsWith(bytes []byte, chr byte) bool {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mapping *Mapping) addValue(key, value I2PString) error {
|
||||||
|
for _, pair := range *mapping.vals {
|
||||||
|
existingKey, _ := pair[0].Data()
|
||||||
|
newKey, _ := key.Data()
|
||||||
|
if existingKey == newKey {
|
||||||
|
return fmt.Errorf("duplicate key: %s", newKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*mapping.vals = append(*mapping.vals, [2]I2PString{key, value})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ReadMapping returns Mapping from a []byte.
|
// ReadMapping returns Mapping from a []byte.
|
||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
|
const MaxMappingSize = 65535 // Match Java I2P's maximum mapping size
|
||||||
|
|
||||||
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error) {
|
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error) {
|
||||||
|
if len(bytes) < 3 {
|
||||||
|
err = append(err, errors.New("mapping data too short"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
size, remainder, e := NewInteger(bytes, 2)
|
||||||
|
if e != nil {
|
||||||
|
log.WithError(e).Error("Failed to read Mapping size")
|
||||||
|
err = append(err, e)
|
||||||
|
}
|
||||||
|
if size.Int() > MaxMappingSize {
|
||||||
|
err = append(err, fmt.Errorf("mapping size %d exceeds maximum %d", size.Int(), MaxMappingSize))
|
||||||
|
return
|
||||||
|
}
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"input_length": len(bytes),
|
"input_length": len(bytes),
|
||||||
}).Debug("Reading Mapping from bytes")
|
}).Debug("Reading Mapping from bytes")
|
||||||
@@ -168,16 +182,16 @@ func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error)
|
|||||||
err = append(err, e)
|
err = append(err, e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
size, remainder, e := NewInteger(bytes, 2)
|
|
||||||
if e != nil {
|
|
||||||
log.WithError(e).Error("Failed to read Mapping size")
|
|
||||||
err = append(err, e)
|
|
||||||
}
|
|
||||||
if size.Int() == 0 {
|
if size.Int() == 0 {
|
||||||
log.Warn("Mapping size is zero")
|
log.Warn("Mapping size is zero")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mapping.size = size
|
mapping.size = size
|
||||||
|
if mapping.size.Int() > len(remainder) {
|
||||||
|
err = append(err, fmt.Errorf("mapping size %d exceeds available data length %d",
|
||||||
|
mapping.size.Int(), len(remainder)))
|
||||||
|
return
|
||||||
|
}
|
||||||
map_bytes := remainder[:mapping.size.Int()]
|
map_bytes := remainder[:mapping.size.Int()]
|
||||||
remainder = remainder[mapping.size.Int():]
|
remainder = remainder[mapping.size.Int():]
|
||||||
if len(remainder) == 0 {
|
if len(remainder) == 0 {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
@@ -11,20 +12,37 @@ import (
|
|||||||
type MappingValues [][2]I2PString
|
type MappingValues [][2]I2PString
|
||||||
|
|
||||||
func (m MappingValues) Get(key I2PString) I2PString {
|
func (m MappingValues) Get(key I2PString) I2PString {
|
||||||
keyBytes, _ := key.Data()
|
if key == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keyBytes, err := key.Data()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"key": string(keyBytes),
|
"key": string(keyBytes),
|
||||||
}).Debug("Searching for key in MappingValues")
|
}).Debug("Searching for key in MappingValues")
|
||||||
|
|
||||||
for _, pair := range m {
|
for _, pair := range m {
|
||||||
kb, _ := pair[0][0:].Data()
|
if pair[0] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
kb, err := pair[0].Data()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if kb == keyBytes {
|
if kb == keyBytes {
|
||||||
|
data, _ := pair[1].Data()
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"key": string(keyBytes),
|
"key": string(keyBytes),
|
||||||
"value": string(pair[1][1:]),
|
"value": string(data),
|
||||||
}).Debug("Found matching key in MappingValues")
|
}).Debug("Found matching key in MappingValues")
|
||||||
return pair[1]
|
return pair[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"key": string(keyBytes),
|
"key": string(keyBytes),
|
||||||
}).Debug("Key not found in MappingValues")
|
}).Debug("Key not found in MappingValues")
|
||||||
@@ -64,10 +82,15 @@ func ValuesToMapping(values MappingValues) *Mapping {
|
|||||||
// In practice routers do not seem to allow duplicate keys.
|
// In practice routers do not seem to allow duplicate keys.
|
||||||
func mappingOrder(values MappingValues) {
|
func mappingOrder(values MappingValues) {
|
||||||
sort.SliceStable(values, func(i, j int) bool {
|
sort.SliceStable(values, func(i, j int) bool {
|
||||||
// Lexographic sort on keys only
|
data1, err1 := values[i][0].Data()
|
||||||
data1, _ := values[i][0].Data()
|
data2, err2 := values[j][0].Data()
|
||||||
data2, _ := values[j][0].Data()
|
|
||||||
return data1 < data2
|
// Handle error cases by treating them as "less than"
|
||||||
|
if err1 != nil || err2 != nil {
|
||||||
|
return err1 == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.Compare([]byte(data1), []byte(data2)) < 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,6 +240,6 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
|
|||||||
"remainder_length": len(remainder_bytes),
|
"remainder_length": len(remainder_bytes),
|
||||||
"error_count": len(errs),
|
"error_count": len(errs),
|
||||||
}).Debug("Finished reading MappingValues")
|
}).Debug("Finished reading MappingValues")
|
||||||
|
remainder_bytes = remainder
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,3 +46,41 @@ func TestMappingOrderSortsValuesThenKeys(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMappingValuesEdgeCases(t *testing.T) {
|
||||||
|
k1, _ := ToI2PString("test")
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mv MappingValues
|
||||||
|
key I2PString
|
||||||
|
want I2PString
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil key",
|
||||||
|
mv: MappingValues{},
|
||||||
|
key: nil,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty mapping",
|
||||||
|
mv: MappingValues{},
|
||||||
|
key: k1,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nil value in pair",
|
||||||
|
mv: MappingValues{{k1, nil}},
|
||||||
|
key: k1,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := tt.mv.Get(tt.key)
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("MappingValues.Get() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -5,7 +5,7 @@ import common "github.com/go-i2p/go-i2p/lib/common/router_identity"
|
|||||||
func Fuzz(data []byte) int {
|
func Fuzz(data []byte) int {
|
||||||
router_identity, _, _ := common.ReadRouterIdentity(data)
|
router_identity, _, _ := common.ReadRouterIdentity(data)
|
||||||
router_identity.Certificate()
|
router_identity.Certificate()
|
||||||
//router_identity.publicKey()
|
// router_identity.publicKey()
|
||||||
//router_identity.signingPublicKey()
|
// router_identity.signingPublicKey()
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ payload :: data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/util/logger"
|
"github.com/go-i2p/go-i2p/lib/util/logger"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
@@ -110,46 +111,46 @@ func (key_certificate KeyCertificate) Data() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SigningPublicKeyType returns the signingPublicKey type as a Go integer.
|
// SigningPublicKeyType returns the signingPublicKey type as a Go integer.
|
||||||
func (key_certificate KeyCertificate) SigningPublicKeyType() (signing_pubkey_type int) {
|
func (key_certificate KeyCertificate) SigningPublicKeyType() int {
|
||||||
signing_pubkey_type = key_certificate.spkType.Int()
|
spk_type := key_certificate.spkType.Int()
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"signing_pubkey_type": signing_pubkey_type,
|
"signing_pubkey_type": spk_type,
|
||||||
}).Debug("Retrieved signingPublicKey type")
|
}).Debug("Retrieved signingPublicKey type")
|
||||||
return key_certificate.spkType.Int()
|
return spk_type
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyType returns the publicKey type as a Go integer.
|
func (key_certificate KeyCertificate) CryptoSize() int {
|
||||||
func (key_certificate KeyCertificate) PublicKeyType() (pubkey_type int) {
|
switch key_certificate.PublicKeyType() {
|
||||||
pubkey_type = key_certificate.cpkType.Int()
|
case KEYCERT_CRYPTO_ELG:
|
||||||
log.WithFields(logrus.Fields{
|
return KEYCERT_CRYPTO_ELG_SIZE
|
||||||
"pubkey_type": pubkey_type,
|
case KEYCERT_CRYPTO_P256:
|
||||||
}).Debug("Retrieved publicKey type")
|
return KEYCERT_CRYPTO_P256_SIZE
|
||||||
return key_certificate.cpkType.Int()
|
case KEYCERT_CRYPTO_P384:
|
||||||
|
return KEYCERT_CRYPTO_P384_SIZE
|
||||||
|
case KEYCERT_CRYPTO_P521:
|
||||||
|
return KEYCERT_CRYPTO_P521_SIZE
|
||||||
|
case KEYCERT_CRYPTO_X25519:
|
||||||
|
return KEYCERT_CRYPTO_X25519_SIZE
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstructPublicKey returns a publicKey constructed using any excess data that may be stored in the KeyCertififcate.
|
|
||||||
// Returns enr errors encountered while parsing.
|
|
||||||
func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_key crypto.PublicKey, err error) {
|
func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_key crypto.PublicKey, err error) {
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"input_length": len(data),
|
"input_length": len(data),
|
||||||
}).Debug("Constructing publicKey from keyCertificate")
|
}).Debug("Constructing publicKey from keyCertificate")
|
||||||
key_type := key_certificate.PublicKeyType()
|
|
||||||
if err != nil {
|
key_type := key_certificate.PublicKeyType()
|
||||||
return
|
|
||||||
}
|
data_len := len(data)
|
||||||
data_len := len(data)
|
if data_len < key_certificate.CryptoSize() {
|
||||||
if data_len < key_certificate.CryptoSize() {
|
return nil, errors.New("error constructing public key: not enough data")
|
||||||
log.WithFields(logrus.Fields{
|
}
|
||||||
"at": "(keyCertificate) ConstructPublicKey",
|
|
||||||
"data_len": data_len,
|
// Implementation missing here - needs to construct appropriate key type
|
||||||
"required_len": KEYCERT_PUBKEY_SIZE,
|
switch key_type {
|
||||||
"reason": "not enough data",
|
case KEYCERT_CRYPTO_ELG:
|
||||||
}).Error("error constructing public key")
|
|
||||||
err = errors.New("error constructing public key: not enough data")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch key_type {
|
|
||||||
case KEYCERT_CRYPTO_ELG:
|
|
||||||
var elg_key crypto.ElgPublicKey
|
var elg_key crypto.ElgPublicKey
|
||||||
copy(elg_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
copy(elg_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
||||||
public_key = elg_key
|
public_key = elg_key
|
||||||
@@ -159,13 +160,25 @@ func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_ke
|
|||||||
copy(ed25519_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
copy(ed25519_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
||||||
public_key = ed25519_key
|
public_key = ed25519_key
|
||||||
log.Debug("Constructed Ed25519PublicKey")
|
log.Debug("Constructed Ed25519PublicKey")
|
||||||
default:
|
case KEYCERT_CRYPTO_P256:
|
||||||
log.WithFields(logrus.Fields{
|
//return crypto.CreatePublicKey(data[:KEYCERT_CRYPTO_P256_SIZE])
|
||||||
"key_type": key_type,
|
case KEYCERT_CRYPTO_P384:
|
||||||
}).Warn("Unknown public key type")
|
//return crypto.CreatePublicKey(data[:KEYCERT_CRYPTO_P384_SIZE])
|
||||||
}
|
case KEYCERT_CRYPTO_P521:
|
||||||
|
//return crypto.CreatePublicKey(data[:KEYCERT_CRYPTO_P521_SIZE])
|
||||||
|
default:
|
||||||
|
return nil, errors.New("error constructing public key: unknown key type")
|
||||||
|
}
|
||||||
|
return nil, errors.New("error constructing public key: unknown key type")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
// PublicKeyType returns the publicKey type as a Go integer.
|
||||||
|
func (key_certificate KeyCertificate) PublicKeyType() int {
|
||||||
|
pk_type := key_certificate.cpkType.Int()
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"pubkey_type": pk_type,
|
||||||
|
}).Debug("Retrieved publicKey type")
|
||||||
|
return pk_type
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstructSigningPublicKey returns a SingingPublicKey constructed using any excess data that may be stored in the KeyCertificate.
|
// ConstructSigningPublicKey returns a SingingPublicKey constructed using any excess data that may be stored in the KeyCertificate.
|
||||||
@@ -268,24 +281,6 @@ func (key_certificate KeyCertificate) SignatureSize() (size int) {
|
|||||||
return sizes[int(key_type)]
|
return sizes[int(key_type)]
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptoSize return the size of a Public Key corresponding to the Key Certificate's publicKey type.
|
|
||||||
func (key_certificate KeyCertificate) CryptoSize() (size int) {
|
|
||||||
sizes := map[int]int{
|
|
||||||
KEYCERT_CRYPTO_ELG: KEYCERT_CRYPTO_ELG_SIZE,
|
|
||||||
KEYCERT_CRYPTO_P256: KEYCERT_CRYPTO_P256_SIZE,
|
|
||||||
KEYCERT_CRYPTO_P384: KEYCERT_CRYPTO_P384_SIZE,
|
|
||||||
KEYCERT_CRYPTO_P521: KEYCERT_CRYPTO_P521_SIZE,
|
|
||||||
KEYCERT_CRYPTO_X25519: KEYCERT_CRYPTO_X25519_SIZE,
|
|
||||||
}
|
|
||||||
key_type := key_certificate.PublicKeyType()
|
|
||||||
size = sizes[int(key_type)]
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"key_type": key_type,
|
|
||||||
"crypto_size": size,
|
|
||||||
}).Debug("Retrieved crypto size")
|
|
||||||
return sizes[int(key_type)]
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewKeyCertificate creates a new *KeyCertificate from []byte using ReadCertificate.
|
// NewKeyCertificate creates a new *KeyCertificate from []byte using ReadCertificate.
|
||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
@@ -300,6 +295,10 @@ func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder
|
|||||||
log.WithError(err).Error("Failed to read Certificate")
|
log.WithError(err).Error("Failed to read Certificate")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if certificate.Type() != 5 { // Key certificate type must be 5
|
||||||
|
return nil, nil, errors.New("error parsing key certificate: invalid certificate type")
|
||||||
|
}
|
||||||
if len(bytes) < KEYCERT_MIN_SIZE {
|
if len(bytes) < KEYCERT_MIN_SIZE {
|
||||||
log.WithError(err).Error("keyCertificate data too short")
|
log.WithError(err).Error("keyCertificate data too short")
|
||||||
err = errors.New("error parsing key certificate: not enough data")
|
err = errors.New("error parsing key certificate: not enough data")
|
||||||
|
@@ -174,7 +174,7 @@ func (router_info *RouterInfo) RouterIdentity() *RouterIdentity {
|
|||||||
// IndentHash returns the identity hash (sha256 sum) for this RouterInfo.
|
// IndentHash returns the identity hash (sha256 sum) for this RouterInfo.
|
||||||
func (router_info *RouterInfo) IdentHash() Hash {
|
func (router_info *RouterInfo) IdentHash() Hash {
|
||||||
log.Debug("Calculating IdentHash for RouterInfo")
|
log.Debug("Calculating IdentHash for RouterInfo")
|
||||||
//data, _ := router_info.RouterIdentity().keyCertificate.Data()
|
// data, _ := router_info.RouterIdentity().keyCertificate.Data()
|
||||||
cert := router_info.RouterIdentity().KeysAndCert.Certificate()
|
cert := router_info.RouterIdentity().KeysAndCert.Certificate()
|
||||||
data := cert.Data()
|
data := cert.Data()
|
||||||
hash := HashData(data)
|
hash := HashData(data)
|
||||||
|
@@ -3,6 +3,7 @@ package signature
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/util/logger"
|
"github.com/go-i2p/go-i2p/lib/util/logger"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@@ -185,7 +185,7 @@ func (v *Ed25519Verifier) Verify(data, sig []byte) (err error) {
|
|||||||
type Ed25519PrivateKey ed25519.PrivateKey
|
type Ed25519PrivateKey ed25519.PrivateKey
|
||||||
|
|
||||||
func (k Ed25519PrivateKey) NewDecrypter() (Decrypter, error) {
|
func (k Ed25519PrivateKey) NewDecrypter() (Decrypter, error) {
|
||||||
//TODO implement me
|
// TODO implement me
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ type SigningPublicKey interface {
|
|||||||
}
|
}
|
||||||
type PublicKey interface {
|
type PublicKey interface {
|
||||||
Len() int
|
Len() int
|
||||||
Bytes() []byte
|
Bytes() []byte
|
||||||
NewEncrypter() (Encrypter, error)
|
NewEncrypter() (Encrypter, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,11 +21,11 @@ type NoiseSession struct {
|
|||||||
*sync.Cond
|
*sync.Cond
|
||||||
*NoiseTransport // The parent transport, which "Dialed" the connection to the peer whith whom we established the session
|
*NoiseTransport // The parent transport, which "Dialed" the connection to the peer whith whom we established the session
|
||||||
*HandshakeState
|
*HandshakeState
|
||||||
RecvQueue *cb.Queue
|
RecvQueue *cb.Queue
|
||||||
SendQueue *cb.Queue
|
SendQueue *cb.Queue
|
||||||
VerifyCallback VerifyCallbackFunc
|
VerifyCallback VerifyCallbackFunc
|
||||||
activeCall int32
|
activeCall int32
|
||||||
Conn net.Conn
|
Conn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAddr implements net.Conn
|
// RemoteAddr implements net.Conn
|
||||||
|
Reference in New Issue
Block a user