Files
Go_I2p/lib/common/router_info/router_info_test.go

249 lines
8.5 KiB
Go

package router_info
import (
"bytes"
"crypto/rand"
"testing"
"time"
"github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
"github.com/go-i2p/go-i2p/lib/common/certificate"
"github.com/go-i2p/go-i2p/lib/common/data"
"github.com/go-i2p/go-i2p/lib/common/key_certificate"
"github.com/go-i2p/go-i2p/lib/common/router_identity"
"github.com/go-i2p/go-i2p/lib/common/signature"
"github.com/go-i2p/go-i2p/lib/crypto"
"github.com/stretchr/testify/assert"
"golang.org/x/crypto/openpgp/elgamal"
"github.com/go-i2p/go-i2p/lib/common/router_address"
)
func generateTestRouterInfo(t *testing.T, publishedTime time.Time) (*RouterInfo, error) {
// Generate signing key pair (Ed25519)
var ed25519_privkey crypto.Ed25519PrivateKey
_, err := (&ed25519_privkey).Generate()
if err != nil {
t.Fatalf("Failed to generate Ed25519 private key: %v\n", err)
}
ed25519_pubkey_raw, err := ed25519_privkey.Public()
if err != nil {
t.Fatalf("Failed to derive Ed25519 public key: %v\n", err)
}
ed25519_pubkey, ok := ed25519_pubkey_raw.(crypto.SigningPublicKey)
if !ok {
t.Fatalf("Failed to get SigningPublicKey from Ed25519 public key")
}
// Generate encryption key pair (ElGamal)
var elgamal_privkey elgamal.PrivateKey
err = crypto.ElgamalGenerate(&elgamal_privkey, rand.Reader)
if err != nil {
t.Fatalf("Failed to generate ElGamal private key: %v\n", err)
}
// Convert elgamal private key to crypto.ElgPrivateKey
var elg_privkey crypto.ElgPrivateKey
xBytes := elgamal_privkey.X.Bytes()
if len(xBytes) > 256 {
t.Fatalf("ElGamal private key X too large")
}
copy(elg_privkey[256-len(xBytes):], xBytes)
// Convert elgamal public key to crypto.ElgPublicKey
var elg_pubkey crypto.ElgPublicKey
yBytes := elgamal_privkey.PublicKey.Y.Bytes()
if len(yBytes) > 256 {
t.Fatalf("ElGamal public key Y too large")
}
copy(elg_pubkey[256-len(yBytes):], yBytes)
// Ensure that elg_pubkey implements crypto.PublicKey interface
var _ crypto.RecievingPublicKey = elg_pubkey
// Create KeyCertificate specifying key types
var payload bytes.Buffer
signingPublicKeyType, err := data.NewIntegerFromInt(7, 2)
if err != nil {
t.Fatalf("Failed to create signing public key type integer: %v", err)
}
cryptoPublicKeyType, err := data.NewIntegerFromInt(0, 2)
if err != nil {
t.Fatalf("Failed to create crypto public key type integer: %v", err)
}
payload.Write(*cryptoPublicKeyType)
payload.Write(*signingPublicKeyType)
// Create KeyCertificate specifying key types
cert, err := certificate.NewCertificateWithType(certificate.CERT_KEY, payload.Bytes())
if err != nil {
t.Fatalf("Failed to create new certificate: %v\n", err)
}
certBytes := cert.Bytes()
t.Logf("Serialized Certificate Size: %d bytes", len(certBytes))
keyCert, err := key_certificate.KeyCertificateFromCertificate(*cert)
if err != nil {
log.Fatalf("KeyCertificateFromCertificate failed: %v\n", err)
}
pubKeySize := keyCert.CryptoSize()
sigKeySize := keyCert.SignatureSize()
paddingSize := keys_and_cert.KEYS_AND_CERT_DATA_SIZE - pubKeySize - sigKeySize
padding := make([]byte, paddingSize)
_, err = rand.Read(padding)
if err != nil {
t.Fatalf("Failed to generate random padding: %v\n", err)
}
// Create RouterIdentity
routerIdentity, err := router_identity.NewRouterIdentity(elg_pubkey, ed25519_pubkey, *cert, padding)
if err != nil {
t.Fatalf("Failed to create router identity: %v\n", err)
}
// create some dummy addresses
options := map[string]string{}
routerAddress, err := router_address.NewRouterAddress(3, <-time.After(1*time.Second), "NTCP2", options)
if err != nil {
t.Fatalf("Failed to create router address: %v\n", err)
}
routerAddresses := []*router_address.RouterAddress{routerAddress}
// create router info
routerInfo, err := NewRouterInfo(routerIdentity, publishedTime, routerAddresses, nil, &ed25519_privkey, signature.SIGNATURE_TYPE_EDDSA_SHA512_ED25519)
if err != nil {
t.Fatalf("Failed to create router info: %v\n", err)
}
return routerInfo, nil
}
// TestRouterInfoCreation verifies that a RouterInfo object can be created without errors.
func TestRouterInfoCreation(t *testing.T) {
assert := assert.New(t)
// Use helper function to generate a RouterInfo
publishedTime := time.Now()
routerInfo, err := generateTestRouterInfo(t, publishedTime)
assert.Nil(err, "RouterInfo creation should not return an error")
assert.NotNil(routerInfo, "RouterInfo should not be nil")
}
// TestRouterInfoPublishedDate verifies that the published date is correctly set and retrieved.
func TestRouterInfoPublishedDate(t *testing.T) {
assert := assert.New(t)
publishedTime := time.Unix(86400, 0) // 1 day since epoch
routerInfo, err := generateTestRouterInfo(t, publishedTime)
assert.Nil(err, "RouterInfo creation should not return an error")
assert.Equal(publishedTime.Unix(), routerInfo.Published().Time().Unix(), "Published date should match the input date")
}
// TestRouterInfoRouterIdentity verifies that the RouterIdentity is correctly set.
func TestRouterInfoRouterIdentity(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
routerIdentity := routerInfo.RouterIdentity()
assert.NotNil(routerIdentity, "RouterIdentity should not be nil")
}
// TestRouterInfoAddresses verifies that the RouterAddresses are correctly set and retrieved.
func TestRouterInfoAddresses(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
addresses := routerInfo.RouterAddresses()
assert.NotNil(addresses, "RouterAddresses should not be nil")
assert.Greater(len(addresses), 0, "RouterAddresses should have at least one address")
}
// TestRouterInfoSerialization verifies that the RouterInfo can be serialized to bytes without error.
func TestRouterInfoSerialization(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
bytes, err := routerInfo.Bytes()
assert.Nil(err, "Serialization should not return an error")
assert.NotNil(bytes, "Serialized bytes should not be nil")
assert.Greater(len(bytes), 0, "Serialized bytes should have a length greater than zero")
}
// TestRouterInfoSignature verifies that the signature is correctly set in the RouterInfo.
func TestRouterInfoSignature(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
signature := routerInfo.Signature()
assert.NotNil(signature, "Signature should not be nil")
}
/* TODO: Fix this
// TestRouterInfoCapabilities verifies the RouterCapabilities method functionality.
func TestRouterInfoCapabilities(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
capabilities := routerInfo.RouterCapabilities()
assert.NotEmpty(capabilities, "RouterCapabilities should not be empty")
}
// TODO: Fix this
// TestRouterInfoVersion verifies the RouterVersion method functionality.
func TestRouterInfoVersion(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
version := routerInfo.RouterVersion()
assert.NotEmpty(version, "RouterVersion should not be empty")
}
*/
// TestRouterInfoGoodVersion verifies the GoodVersion method functionality.
func TestRouterInfoGoodVersion(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
isGoodVersion := routerInfo.GoodVersion()
assert.IsType(true, isGoodVersion, "GoodVersion should return a boolean")
}
// TestRouterInfoUnCongested verifies the UnCongested method functionality.
func TestRouterInfoUnCongested(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
isUncongested := routerInfo.UnCongested()
assert.IsType(true, isUncongested, "UnCongested should return a boolean")
}
// TestRouterInfoReachable verifies the Reachable method functionality.
func TestRouterInfoReachable(t *testing.T) {
assert := assert.New(t)
routerInfo, err := generateTestRouterInfo(t, time.Now())
assert.Nil(err, "RouterInfo creation should not return an error")
isReachable := routerInfo.Reachable()
assert.IsType(true, isReachable, "Reachable should return a boolean")
}