Merge branch 'master' of github.com:go-i2p/go-i2p into ntcp
This commit is contained in:
@ -282,9 +282,9 @@ func GetSignatureTypeFromCertificate(cert Certificate) (int, error) {
|
||||
if cert.Type() != CERT_KEY {
|
||||
return 0, fmt.Errorf("unexpected certificate type: %d", cert.Type())
|
||||
}
|
||||
if len(cert.payload) < 2 {
|
||||
if len(cert.payload) < 4 {
|
||||
return 0, fmt.Errorf("certificate payload too short to contain signature type")
|
||||
}
|
||||
sigType := int(binary.BigEndian.Uint16(cert.payload[0:2]))
|
||||
sigType := int(binary.BigEndian.Uint16(cert.payload[2:4])) // Changed offset to read signing key type
|
||||
return sigType, nil
|
||||
}
|
||||
|
@ -28,16 +28,29 @@ func (i Integer) Bytes() []byte {
|
||||
return i[:]
|
||||
}
|
||||
|
||||
// Int returns the Date as a Go integer
|
||||
// Int returns the Integer as a Go integer
|
||||
func (i Integer) Int() int {
|
||||
return intFromBytes(i.Bytes())
|
||||
}
|
||||
|
||||
// Interpret a slice of bytes from length 0 to length 8 as a big-endian
|
||||
// integer and return an int representation.
|
||||
func intFromBytes(number []byte) (value int) {
|
||||
numLen := len(number)
|
||||
if numLen < MAX_INTEGER_SIZE {
|
||||
paddedNumber := make([]byte, MAX_INTEGER_SIZE)
|
||||
copy(paddedNumber[MAX_INTEGER_SIZE-numLen:], number)
|
||||
number = paddedNumber
|
||||
}
|
||||
value = int(binary.BigEndian.Uint64(number))
|
||||
return
|
||||
}
|
||||
|
||||
// ReadInteger returns an Integer from a []byte of specified length.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
func ReadInteger(bytes []byte, size int) (Integer, []byte) {
|
||||
if len(bytes) < size {
|
||||
return bytes[:size], bytes[len(bytes):]
|
||||
return bytes, nil
|
||||
}
|
||||
return bytes[:size], bytes[size:]
|
||||
}
|
||||
@ -46,13 +59,7 @@ func ReadInteger(bytes []byte, size int) (Integer, []byte) {
|
||||
// Limits the length of the created Integer to MAX_INTEGER_SIZE.
|
||||
// Returns a pointer to Integer unlike ReadInteger.
|
||||
func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error) {
|
||||
integerSize := MAX_INTEGER_SIZE
|
||||
if size < MAX_INTEGER_SIZE {
|
||||
integerSize = size
|
||||
}
|
||||
intBytes := bytes[:integerSize]
|
||||
remainder = bytes[integerSize:]
|
||||
i, _ := ReadInteger(intBytes, integerSize)
|
||||
i, remainder := ReadInteger(bytes, size)
|
||||
integer = &i
|
||||
return
|
||||
}
|
||||
@ -69,17 +76,3 @@ func NewIntegerFromInt(value int, size int) (integer *Integer, err error) {
|
||||
integer = objinteger
|
||||
return
|
||||
}
|
||||
|
||||
// Interpret a slice of bytes from length 0 to length 8 as a big-endian
|
||||
// integer and return an int representation.
|
||||
func intFromBytes(number []byte) (value int) {
|
||||
num_len := len(number)
|
||||
if num_len < MAX_INTEGER_SIZE {
|
||||
number = append(
|
||||
make([]byte, MAX_INTEGER_SIZE-num_len),
|
||||
number...,
|
||||
)
|
||||
}
|
||||
value = int(binary.BigEndian.Uint64(number))
|
||||
return
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ payload :: data
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/signature"
|
||||
|
||||
"github.com/go-i2p/logger"
|
||||
@ -148,7 +148,7 @@ func (keyCertificate KeyCertificate) ConstructPublicKey(data []byte) (public_key
|
||||
"required_len": KEYCERT_PUBKEY_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error constructing public key")
|
||||
err = errors.New("error constructing public key: not enough data")
|
||||
err = fmt.Errorf("error constructing public key: not enough data")
|
||||
return
|
||||
}
|
||||
switch key_type {
|
||||
@ -240,7 +240,7 @@ func (keyCertificate KeyCertificate) ConstructSigningPublicKey(data []byte) (sig
|
||||
"required_len": KEYCERT_SPK_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error constructing signing public key")
|
||||
err = errors.New("error constructing signing public key: not enough data")
|
||||
err = fmt.Errorf("error constructing signing public key: not enough data")
|
||||
return
|
||||
}
|
||||
switch signing_key_type {
|
||||
@ -297,7 +297,7 @@ func (keyCertificate KeyCertificate) ConstructSigningPublicKey(data []byte) (sig
|
||||
log.WithFields(logrus.Fields{
|
||||
"signing_key_type": signing_key_type,
|
||||
}).Warn("Unknown signing key type")
|
||||
panic(err)
|
||||
return nil, fmt.Errorf("unknown signing key type")
|
||||
}
|
||||
|
||||
return
|
||||
@ -364,19 +364,23 @@ func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder
|
||||
return
|
||||
}
|
||||
|
||||
payload := certificate.Data()
|
||||
if certificate.Type() != CERT_KEY {
|
||||
return nil, remainder, fmt.Errorf("invalid certificate type: %d", certificate.Type())
|
||||
}
|
||||
|
||||
cpkTypeBytes := payload[0:2]
|
||||
spkTypeBytes := payload[2:4]
|
||||
|
||||
cpkType := Integer(cpkTypeBytes)
|
||||
spkType := Integer(spkTypeBytes)
|
||||
if len(certificate.Data()) < 4 {
|
||||
return nil, remainder, fmt.Errorf("key certificate data too short")
|
||||
}
|
||||
log.Println("Certificate Data in NewKeyCertificate: ", certificate.Data()[0:2], certificate.Data()[2:4])
|
||||
|
||||
cpkType, _ := ReadInteger(certificate.Data()[2:4], 2)
|
||||
spkType, _ := ReadInteger(certificate.Data()[0:2], 2)
|
||||
key_certificate = &KeyCertificate{
|
||||
Certificate: certificate,
|
||||
SpkType: spkType,
|
||||
CpkType: cpkType,
|
||||
SpkType: spkType,
|
||||
}
|
||||
log.Println("cpkType in NewKeyCertificate: ", cpkType.Int(), "spkType in NewKeyCertificate: ", spkType.Int())
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"spk_type": key_certificate.SpkType.Int(),
|
||||
|
@ -1,75 +1,66 @@
|
||||
package key_certificate
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
/*
|
||||
//TODO: Redo these tests
|
||||
func TestSigningPublicKeyTypeReturnsCorrectInteger(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
func TestSingingPublicKeyTypeReturnsCorrectInteger(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
// Create certificate with signing key type P521 (3)
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x07})
|
||||
assert.Nil(err)
|
||||
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00})
|
||||
pk_type := key_cert.SigningPublicKeyType()
|
||||
pk_type := key_cert.SigningPublicKeyType()
|
||||
assert.Equal(KEYCERT_SIGN_ED25519, pk_type, "SigningPublicKeyType() did not return correct type")
|
||||
}
|
||||
|
||||
assert.Nil(err, "SigningPublicKeyType() returned error with valid data")
|
||||
assert.Equal(pk_type, KEYCERT_SIGN_P521, "SigningPublicKeyType() did not return correct typec")
|
||||
}
|
||||
func TestSigningPublicKeyTypeWithInvalidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
func TestSingingPublicKeyTypeReportsWhenDataTooSmall(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
// Test with invalid short data
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x01, 0x00})
|
||||
assert.NotNil(err)
|
||||
assert.Contains(err.Error(), "key certificate data too short")
|
||||
assert.Nil(key_cert)
|
||||
}
|
||||
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x01, 0x00})
|
||||
func TestPublicKeyTypeReturnsCorrectInteger(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
assert.NotNil(err, "Expected error when data is too small")
|
||||
assert.Equal("key certificate payload too short", err.Error(), "Correct error message should be returned")
|
||||
assert.Nil(key_cert, "key_cert should be nil when an error occurs")
|
||||
// Create certificate with crypto type ELG (0)
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00})
|
||||
assert.Nil(err)
|
||||
|
||||
if key_cert != nil {
|
||||
sk_type := key_cert.SigningPublicKeyType()
|
||||
assert.Equal(sk_type, 0, "SigningPublicKeyType() did not return correct type")
|
||||
}
|
||||
}
|
||||
pk_type := key_cert.PublicKeyType()
|
||||
assert.Equal(KEYCERT_CRYPTO_ELG, pk_type, "PublicKeyType() did not return correct type")
|
||||
}
|
||||
|
||||
func TestPublicKeyTypeReturnsCorrectInteger(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
func TestPublicKeyTypeWithInvalidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03})
|
||||
pk_type := key_cert.PublicKeyType()
|
||||
// Test with invalid short data
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x02})
|
||||
assert.NotNil(err)
|
||||
assert.Contains(err.Error(), "key certificate data too short", "Expected error for invalid data")
|
||||
assert.Nil(key_cert)
|
||||
}
|
||||
|
||||
assert.Nil(err, "publicKey() returned error with valid data")
|
||||
assert.Equal(pk_type, KEYCERT_SIGN_P521, "PublicKeyType() did not return correct typec")
|
||||
}
|
||||
func TestConstructPublicKeyWithInsufficientData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
func TestPublicKeyTypeReportsWhenDataTooSmall(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00})
|
||||
assert.Nil(err)
|
||||
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x02, 0x00, 0x00})
|
||||
// Test with data smaller than required size
|
||||
data := make([]byte, 255) // ELG requires 256 bytes
|
||||
_, err = key_cert.ConstructPublicKey(data)
|
||||
|
||||
assert.NotNil(err, "Expected error when data is too small")
|
||||
assert.Equal("key certificate payload too short", err.Error(), "Correct error message should be returned")
|
||||
assert.Nil(key_cert, "key_cert should be nil when an error occurs")
|
||||
|
||||
if key_cert != nil {
|
||||
pk_type := key_cert.PublicKeyType()
|
||||
assert.Equal(pk_type, 0, "PublicKeyType() did not return correct type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstructPublicKeyReportsWhenDataTooSmall(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00})
|
||||
data := make([]byte, 255)
|
||||
_, err = key_cert.ConstructPublicKey(data)
|
||||
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error constructing public key: not enough data", err.Error(), "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
*/
|
||||
assert.NotNil(err)
|
||||
assert.Equal("error constructing public key: not enough data", err.Error())
|
||||
}
|
||||
func TestConstructPublicKeyReturnsCorrectDataWithElg(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
@ -4,6 +4,7 @@ package router_info
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -237,7 +238,6 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
"required_len": ROUTER_INFO_MIN_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error parsing router info")
|
||||
err = errors.New("error parsing router info: not enough data to read identity")
|
||||
return
|
||||
}
|
||||
info.published, remainder, err = NewDate(remainder)
|
||||
@ -248,7 +248,6 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
"required_len": DATE_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error parsing router info")
|
||||
err = errors.New("error parsing router info: not enough data to read publish date")
|
||||
}
|
||||
info.size, remainder, err = NewInteger(remainder, 1)
|
||||
if err != nil {
|
||||
@ -269,7 +268,6 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
//"required_len": ROUTER_ADDRESS_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error parsing router address")
|
||||
err = errors.New("error parsing router info: not enough data to read router addresses")
|
||||
}
|
||||
info.addresses = append(info.addresses, &address)
|
||||
}
|
||||
@ -291,9 +289,31 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
for _, e := range errs {
|
||||
estring += e.Error() + " "
|
||||
}
|
||||
err = errors.New("error parsing router info: " + estring)
|
||||
}
|
||||
sigType, err := certificate.GetSignatureTypeFromCertificate(info.router_identity.Certificate())
|
||||
// Add debug logging for certificate inspection
|
||||
cert := info.router_identity.Certificate()
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(RouterInfo) ReadRouterInfo",
|
||||
"cert_type": cert.Type(),
|
||||
"cert_length": cert.Length(),
|
||||
"remainder_len": len(remainder),
|
||||
}).Debug("Processing certificate")
|
||||
|
||||
sigType, err := certificate.GetSignatureTypeFromCertificate(cert)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to get signature type from certificate")
|
||||
return RouterInfo{}, remainder, fmt.Errorf("certificate signature type error: %v", err)
|
||||
}
|
||||
|
||||
// Enhanced signature type validation
|
||||
if sigType <= SIGNATURE_TYPE_RSA_SHA256_2048 || sigType > SIGNATURE_TYPE_REDDSA_SHA512_ED25519 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"sigType": sigType,
|
||||
"cert": cert,
|
||||
}).Error("Invalid signature type detected")
|
||||
return RouterInfo{}, remainder, fmt.Errorf("invalid signature type: %d", sigType)
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"sigType": sigType,
|
||||
}).Debug("Got sigType")
|
||||
|
Reference in New Issue
Block a user