!WIP! - Router Info

This commit is contained in:
Haris Khan
2024-11-09 00:53:17 -05:00
parent 4020db8a19
commit 98d05e27c8
15 changed files with 521 additions and 95 deletions

View File

@@ -38,7 +38,8 @@ type Destination struct {
func (destination Destination) Base32Address() (str string) {
log.Debug("Generating Base32 address for Destination")
dest := destination.KeysAndCert.KeyCertificate.Bytes()
cert := destination.KeysAndCert.Certificate()
dest := cert.Bytes()
hash := crypto.SHA256(dest)
str = strings.Trim(base32.EncodeToString(hash[:]), "=")
str = str + ".b32.i2p"
@@ -54,7 +55,8 @@ func (destination Destination) Base32Address() (str string) {
func (destination Destination) Base64() string {
log.Debug("Generating Base64 address for Destination")
dest := destination.KeysAndCert.KeyCertificate.Bytes()
cert := destination.KeysAndCert.Certificate()
dest := cert.Bytes()
base64Address := base64.EncodeToString(dest)
log.WithFields(logrus.Fields{

View File

@@ -5,7 +5,7 @@ import common "github.com/go-i2p/go-i2p/lib/common/router_identity"
func Fuzz(data []byte) int {
router_identity, _, _ := common.ReadRouterIdentity(data)
router_identity.Certificate()
router_identity.PublicKey()
router_identity.SigningPublicKey()
router_identity.publicKey()
router_identity.signingPublicKey()
return 0
}

View File

@@ -29,7 +29,6 @@ payload :: data
import (
"errors"
"github.com/go-i2p/go-i2p/lib/util/logger"
"github.com/sirupsen/logrus"
@@ -66,7 +65,7 @@ const (
KEYCERT_MIN_SIZE = 7
)
// SigningPublicKey sizes for Signing Key Types
// signingPublicKey sizes for Signing Key Types
const (
KEYCERT_SIGN_DSA_SHA1_SIZE = 128
KEYCERT_SIGN_P256_SIZE = 64
@@ -79,7 +78,7 @@ const (
KEYCERT_SIGN_ED25519PH_SIZE = 32
)
// PublicKey sizes for Public Key Types
// publicKey sizes for Public Key Types
const (
KEYCERT_CRYPTO_ELG_SIZE = 256
KEYCERT_CRYPTO_P256_SIZE = 64
@@ -106,34 +105,34 @@ func (key_certificate KeyCertificate) Data() ([]byte, error) {
data := key_certificate.Certificate.RawBytes()
log.WithFields(logrus.Fields{
"data_length": len(data),
}).Debug("Retrieved raw data from KeyCertificate")
}).Debug("Retrieved raw data from keyCertificate")
return key_certificate.Certificate.RawBytes(), nil
}
// 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) {
signing_pubkey_type = key_certificate.spkType.Int()
log.WithFields(logrus.Fields{
"signing_pubkey_type": signing_pubkey_type,
}).Debug("Retrieved SigningPublicKey type")
}).Debug("Retrieved signingPublicKey type")
return key_certificate.spkType.Int()
}
// PublicKeyType returns the PublicKey type as a Go integer.
// PublicKeyType returns the publicKey type as a Go integer.
func (key_certificate KeyCertificate) PublicKeyType() (pubkey_type int) {
pubkey_type = key_certificate.cpkType.Int()
log.WithFields(logrus.Fields{
"pubkey_type": pubkey_type,
}).Debug("Retrieved PublicKey type")
}).Debug("Retrieved publicKey type")
return key_certificate.cpkType.Int()
}
// ConstructPublicKey returns a PublicKey constructed using any excess data that may be stored in the KeyCertififcate.
// 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) {
log.WithFields(logrus.Fields{
"input_length": len(data),
}).Debug("Constructing PublicKey from KeyCertificate")
}).Debug("Constructing publicKey from keyCertificate")
key_type := key_certificate.PublicKeyType()
if err != nil {
return
@@ -141,7 +140,7 @@ func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_ke
data_len := len(data)
if data_len < key_certificate.CryptoSize() {
log.WithFields(logrus.Fields{
"at": "(KeyCertificate) ConstructPublicKey",
"at": "(keyCertificate) ConstructPublicKey",
"data_len": data_len,
"required_len": KEYCERT_PUBKEY_SIZE,
"reason": "not enough data",
@@ -174,7 +173,7 @@ func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_ke
func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (signing_public_key crypto.SigningPublicKey, err error) {
log.WithFields(logrus.Fields{
"input_length": len(data),
}).Debug("Constructing SigningPublicKey from KeyCertificate")
}).Debug("Constructing signingPublicKey from keyCertificate")
signing_key_type := key_certificate.PublicKeyType()
if err != nil {
return
@@ -182,7 +181,7 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
data_len := len(data)
if data_len < key_certificate.SignatureSize() {
log.WithFields(logrus.Fields{
"at": "(KeyCertificate) ConstructSigningPublicKey",
"at": "(keyCertificate) ConstructSigningPublicKey",
"data_len": data_len,
"required_len": KEYCERT_SPK_SIZE,
"reason": "not enough data",
@@ -247,7 +246,7 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
return
}
// SignatureSize return the size of a Signature corresponding to the Key Certificate's SigningPublicKey type.
// SignatureSize return the size of a Signature corresponding to the Key Certificate's signingPublicKey type.
func (key_certificate KeyCertificate) SignatureSize() (size int) {
sizes := map[int]int{
KEYCERT_SIGN_DSA_SHA1: KEYCERT_SIGN_DSA_SHA1_SIZE,
@@ -269,7 +268,7 @@ func (key_certificate KeyCertificate) SignatureSize() (size int) {
return sizes[int(key_type)]
}
// CryptoSize return the size of a Public Key corresponding to the Key Certificate's PublicKey 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,
@@ -293,7 +292,7 @@ func (key_certificate KeyCertificate) CryptoSize() (size int) {
func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder []byte, err error) {
log.WithFields(logrus.Fields{
"input_length": len(bytes),
}).Debug("Creating new KeyCertificate")
}).Debug("Creating new keyCertificate")
var certificate Certificate
certificate, remainder, err = ReadCertificate(bytes)
@@ -302,9 +301,9 @@ func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder
return
}
if len(bytes) < KEYCERT_MIN_SIZE {
log.WithError(err).Error("keyCertificate data too short")
err = errors.New("error parsing key certificate: not enough data")
remainder = bytes[KEYCERT_MIN_SIZE:]
log.WithError(err).Error("KeyCertificate data too short")
}
key_certificate = &KeyCertificate{
Certificate: certificate,
@@ -320,20 +319,20 @@ func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder
"spk_type": key_certificate.spkType.Int(),
"cpk_type": key_certificate.cpkType.Int(),
"remainder_length": len(remainder),
}).Debug("Successfully created new KeyCertificate")
}).Debug("Successfully created new keyCertificate")
return
}
// KeyCertificateFromCertificate returns a *KeyCertificate from a *Certificate.
func KeyCertificateFromCertificate(certificate Certificate) *KeyCertificate {
log.Debug("Creating KeyCertificate from Certificate")
log.Debug("Creating keyCertificate from Certificate")
// k, _, _ := NewKeyCertificate(certificate.RawBytes())
k, _, err := NewKeyCertificate(certificate.RawBytes())
if err != nil {
log.WithError(err).Error("Failed to create KeyCertificate from Certificate")
log.WithError(err).Error("Failed to create keyCertificate from Certificate")
} else {
log.Debug("Successfully created KeyCertificate from Certificate")
log.Debug("Successfully created keyCertificate from Certificate")
}
return k
}

View File

@@ -35,7 +35,7 @@ func TestPublicKeyTypeReturnsCorrectInteger(t *testing.T) {
key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03})
pk_type := key_cert.PublicKeyType()
assert.Nil(err, "PublicKey() returned error with valid data")
assert.Nil(err, "publicKey() returned error with valid data")
assert.Equal(pk_type, KEYCERT_SIGN_P521, "PublicKeyType() did not return correct typec")
}
@@ -94,7 +94,7 @@ func TestConstructSigningPublicKeyWithDSASHA1(t *testing.T) {
spk, err := key_cert.ConstructSigningPublicKey(data)
assert.Nil(err, "ConstructSigningPublicKey() with DSA SHA1 returned error with valid data")
assert.Equal(spk.Len(), KEYCERT_SIGN_DSA_SHA1_SIZE, "ConstructSigningPublicKey() with DSA SHA1 returned incorrect SigningPublicKey length")
assert.Equal(spk.Len(), KEYCERT_SIGN_DSA_SHA1_SIZE, "ConstructSigningPublicKey() with DSA SHA1 returned incorrect signingPublicKey length")
}
func TestConstructSigningPublicKeyWithP256(t *testing.T) {
@@ -105,7 +105,7 @@ func TestConstructSigningPublicKeyWithP256(t *testing.T) {
spk, err := key_cert.ConstructSigningPublicKey(data)
assert.Nil(err, "ConstructSigningPublicKey() with P256 returned err on valid data")
assert.Equal(spk.Len(), KEYCERT_SIGN_P256_SIZE, "ConstructSigningPublicKey() with P256 returned incorrect SigningPublicKey length")
assert.Equal(spk.Len(), KEYCERT_SIGN_P256_SIZE, "ConstructSigningPublicKey() with P256 returned incorrect signingPublicKey length")
}
func TestConstructSigningPublicKeyWithP384(t *testing.T) {
@@ -116,7 +116,7 @@ func TestConstructSigningPublicKeyWithP384(t *testing.T) {
spk, err := key_cert.ConstructSigningPublicKey(data)
assert.Nil(err, "ConstructSigningPublicKey() with P384 returned err on valid data")
assert.Equal(spk.Len(), KEYCERT_SIGN_P384_SIZE, "ConstructSigningPublicKey() with P384 returned incorrect SigningPublicKey length")
assert.Equal(spk.Len(), KEYCERT_SIGN_P384_SIZE, "ConstructSigningPublicKey() with P384 returned incorrect signingPublicKey length")
}
func TestConstructSigningPublicKeyWithP521(t *testing.T) {
@@ -127,5 +127,5 @@ func TestConstructSigningPublicKeyWithP521(t *testing.T) {
spk, err := key_cert.ConstructSigningPublicKey(data)
assert.Nil(err, "ConstructSigningPublicKey() with P521 returned err on valid data")
assert.Equal(spk.Len(), KEYCERT_SIGN_P521_SIZE, "ConstructSigningPublicKey() with P521 returned incorrect SigningPublicKey length")
assert.Equal(spk.Len(), KEYCERT_SIGN_P521_SIZE, "ConstructSigningPublicKey() with P521 returned incorrect signingPublicKey length")
}

View File

@@ -30,7 +30,7 @@ Description
An encryption public key, a signing public key, and a certificate, used as either a RouterIdentity or a Destination.
Contents
A PublicKey followed by a SigningPublicKey and then a Certificate.
A publicKey followed by a signingPublicKey and then a Certificate.
+----+----+----+----+----+----+----+----+
| public_key |
@@ -55,14 +55,14 @@ A PublicKey followed by a SigningPublicKey and then a Certificate.
| certificate |
+----+----+----+-//
public_key :: PublicKey (partial or full)
public_key :: publicKey (partial or full)
length -> 256 bytes or as specified in key certificate
padding :: random data
length -> 0 bytes or as specified in key certificate
padding length + signing_key length == 128 bytes
signing__key :: SigningPublicKey (partial or full)
signing__key :: signingPublicKey (partial or full)
length -> 128 bytes or as specified in key certificate
padding length + signing_key length == 128 bytes
@@ -76,34 +76,34 @@ total length: 387+ bytes
//
// https://geti2p.net/spec/common-structures#keysandcert
type KeysAndCert struct {
KeyCertificate *KeyCertificate
keyCertificate *KeyCertificate
publicKey crypto.PublicKey
padding []byte
Padding []byte
signingPublicKey crypto.SigningPublicKey
}
// Bytes returns the entire KeyCertificate in []byte form, trims payload to specified length.
// Bytes returns the entire keyCertificate in []byte form, trims payload to specified length.
func (keys_and_cert KeysAndCert) Bytes() []byte {
bytes := keys_and_cert.KeyCertificate.Bytes()
bytes := keys_and_cert.keyCertificate.Bytes()
log.WithFields(logrus.Fields{
"bytes_length": len(bytes),
}).Debug("Retrieved bytes from KeysAndCert")
return bytes
}
// PublicKey returns the public key as a crypto.PublicKey.
// publicKey returns the public key as a crypto.publicKey.
func (keys_and_cert *KeysAndCert) PublicKey() (key crypto.PublicKey) {
return keys_and_cert.publicKey
}
// SigningPublicKey returns the signing public key.
// signingPublicKey returns the signing public key.
func (keys_and_cert *KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey) {
return keys_and_cert.signingPublicKey
}
// Certfificate returns the certificate.
func (keys_and_cert *KeysAndCert) Certificate() (cert Certificate) {
return keys_and_cert.KeyCertificate.Certificate
return keys_and_cert.keyCertificate.Certificate
}
// ReadKeysAndCert creates a new *KeysAndCert from []byte using ReadKeysAndCert.
@@ -123,7 +123,7 @@ func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte,
"reason": "not enough data",
}).Error("error parsing keys and cert")
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
keys_and_cert.KeyCertificate, remainder, _ = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
keys_and_cert.keyCertificate, remainder, _ = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
return
} else if data_len < KEYS_AND_CERT_DATA_SIZE {
log.WithFields(logrus.Fields{
@@ -135,30 +135,30 @@ func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte,
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
return
}
keys_and_cert.KeyCertificate, remainder, err = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
keys_and_cert.keyCertificate, remainder, err = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
if err != nil {
log.WithError(err).Error("Failed to create KeyCertificate")
log.WithError(err).Error("Failed to create keyCertificate")
return
}
// TODO: this only supports one key type right now and it's the old key type, but the layout is the same.
// a case-switch which sets the size of the SPK and the PK should be used to replace the referenced KEYS_AND_CERT_PUBKEY_SIZE
// and KEYS_AND_CERT_SPK_SIZE constants in the future.
keys_and_cert.publicKey, err = keys_and_cert.KeyCertificate.ConstructPublicKey(data[:keys_and_cert.KeyCertificate.CryptoSize()])
keys_and_cert.publicKey, err = keys_and_cert.keyCertificate.ConstructPublicKey(data[:keys_and_cert.keyCertificate.CryptoSize()])
if err != nil {
log.WithError(err).Error("Failed to construct PublicKey")
log.WithError(err).Error("Failed to construct publicKey")
return
}
keys_and_cert.signingPublicKey, err = keys_and_cert.KeyCertificate.ConstructSigningPublicKey(data[KEYS_AND_CERT_DATA_SIZE-keys_and_cert.KeyCertificate.SignatureSize() : KEYS_AND_CERT_DATA_SIZE])
keys_and_cert.signingPublicKey, err = keys_and_cert.keyCertificate.ConstructSigningPublicKey(data[KEYS_AND_CERT_DATA_SIZE-keys_and_cert.keyCertificate.SignatureSize() : KEYS_AND_CERT_DATA_SIZE])
if err != nil {
log.WithError(err).Error("Failed to construct SigningPublicKey")
log.WithError(err).Error("Failed to construct signingPublicKey")
return
}
padding := data[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_DATA_SIZE-KEYS_AND_CERT_SPK_SIZE]
keys_and_cert.padding = padding
keys_and_cert.Padding = padding
log.WithFields(logrus.Fields{
"public_key_type": keys_and_cert.KeyCertificate.PublicKeyType(),
"signing_public_key_type": keys_and_cert.KeyCertificate.SigningPublicKeyType(),
"public_key_type": keys_and_cert.keyCertificate.PublicKeyType(),
"signing_public_key_type": keys_and_cert.keyCertificate.SigningPublicKeyType(),
"padding_length": len(padding),
"remainder_length": len(remainder),
}).Debug("Successfully read KeysAndCert")
@@ -166,3 +166,66 @@ func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte,
return
}
// NewKeysAndCert creates a new KeysAndCert instance with the provided parameters.
// It validates the sizes of the provided keys and padding before assembling the struct.
func NewKeysAndCert(
keyCertificate *KeyCertificate,
publicKey crypto.PublicKey,
padding []byte,
signingPublicKey crypto.SigningPublicKey,
) (*KeysAndCert, error) {
log.Debug("Creating new KeysAndCert with provided parameters")
// 1. Validate keyCertificate
if keyCertificate == nil {
log.Error("KeyCertificate is nil")
return nil, errors.New("KeyCertificate cannot be nil")
}
// 2. Validate publicKey size
if publicKey.Len() != KEYS_AND_CERT_PUBKEY_SIZE {
log.WithFields(logrus.Fields{
"expected_size": KEYS_AND_CERT_PUBKEY_SIZE,
"actual_size": publicKey.Len(),
}).Error("Invalid publicKey size")
return nil, errors.New("publicKey has an invalid size")
}
/*
// 3. Validate signingPublicKey size
if signingPublicKey.Len() != KEYS_AND_CERT_SPK_SIZE {
log.WithFields(logrus.Fields{
"expected_size": KEYS_AND_CERT_SPK_SIZE,
"actual_size": signingPublicKey.Len(),
}).Error("Invalid signingPublicKey size")
return nil, errors.New("signingPublicKey has an invalid size")
}
*/
// 4. Validate padding size
expectedPaddingSize := KEYS_AND_CERT_DATA_SIZE - KEYS_AND_CERT_PUBKEY_SIZE - KEYS_AND_CERT_SPK_SIZE
if len(padding) != expectedPaddingSize {
log.WithFields(logrus.Fields{
"expected_size": expectedPaddingSize,
"actual_size": len(padding),
}).Error("Invalid padding size")
return nil, errors.New("padding has an invalid size")
}
// 5. Assemble KeysAndCert
keysAndCert := &KeysAndCert{
keyCertificate: keyCertificate,
publicKey: publicKey,
Padding: padding,
signingPublicKey: signingPublicKey,
}
log.WithFields(logrus.Fields{
"public_key_length": publicKey.Len(),
"signing_public_key_length": signingPublicKey.Len(),
"padding_length": len(padding),
}).Debug("Successfully created KeysAndCert")
return keysAndCert, nil
}

View File

@@ -32,13 +32,13 @@ Accurate for version 0.9.49
Description
Contains all of the currently authorized Leases for a particular Destination, the
PublicKey to which garlic messages can be encrypted, and then the SigningPublicKey
publicKey to which garlic messages can be encrypted, and then the signingPublicKey
that can be used to revoke this particular version of the structure. The LeaseSet is one
of the two structures stored in the network database (the other being RouterInfo), and
is kered under the SHA256 of the contained Destination.
Contents
Destination, followed by a PublicKey for encryption, then a SigningPublicKey which
Destination, followed by a publicKey for encryption, then a signingPublicKey which
can be used to revoke this version of the LeaseSet, then a 1 byte Integer specifying how
many Lease structures are in the set, followed by the actual Lease structures and
finally a Signature of the previous bytes signed by the Destination's SigningPrivateKey.
@@ -100,10 +100,10 @@ finally a Signature of the previous bytes signed by the Destination's SigningPri
destination :: Destination
length -> >= 387 bytes
encryption_key :: PublicKey
encryption_key :: publicKey
length -> 256 bytes
signing_key :: SigningPublicKey
signing_key :: signingPublicKey
length -> 128 bytes or as specified in destination's key certificate
num :: Integer
@@ -157,7 +157,7 @@ func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error
remainder_len := len(remainder)
if remainder_len < LEASE_SET_PUBKEY_SIZE {
log.WithFields(logrus.Fields{
"at": "(LeaseSet) PublicKey",
"at": "(LeaseSet) publicKey",
"data_len": remainder_len,
"required_len": LEASE_SET_PUBKEY_SIZE,
"reason": "not enough data",
@@ -167,7 +167,7 @@ func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error
return
}
copy(public_key[:], remainder[:LEASE_SET_PUBKEY_SIZE])
log.Debug("Successfully retrieved PublicKey from LeaseSet")
log.Debug("Successfully retrieved publicKey from LeaseSet")
return
}
@@ -200,11 +200,11 @@ func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicK
}
if cert_len == 0 {
// No Certificate is present, return the LEASE_SET_SPK_SIZE byte
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
// signingPublicKey space as legacy DSA SHA1 signingPublicKey.
var dsa_pk crypto.DSAPublicKey
copy(dsa_pk[:], lease_set[offset:offset+LEASE_SET_SPK_SIZE])
signing_public_key = dsa_pk
log.Debug("Retrieved legacy DSA SHA1 SigningPublicKey")
log.Debug("Retrieved legacy DSA SHA1 signingPublicKey")
} else {
// A Certificate is present in this LeaseSet's Destination
cert_type := cert.Type()
@@ -216,17 +216,17 @@ func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicK
lease_set[offset : offset+LEASE_SET_SPK_SIZE],
)
if err != nil {
log.WithError(err).Error("Failed to construct SigningPublicKey from KeyCertificate")
log.WithError(err).Error("Failed to construct signingPublicKey from keyCertificate")
} else {
log.Debug("Retrieved SigningPublicKey from KeyCertificate")
log.Debug("Retrieved signingPublicKey from keyCertificate")
}
} else {
// No Certificate is present, return the LEASE_SET_SPK_SIZE byte
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
// signingPublicKey space as legacy DSA SHA1 signingPublicKey.
var dsa_pk crypto.DSAPublicKey
copy(dsa_pk[:], lease_set[offset:offset+LEASE_SET_SPK_SIZE])
signing_public_key = dsa_pk
log.Debug("Retrieved legacy DSA SHA1 SigningPublicKey (Certificate present but not Key Certificate)")
log.Debug("Retrieved legacy DSA SHA1 signingPublicKey (Certificate present but not Key Certificate)")
}
}
return
@@ -358,7 +358,7 @@ func (lease_set LeaseSet) Verify() error {
//data := lease_set[:data_end]
//spk, _ := lease_set.
// Destination().
// SigningPublicKey()
// signingPublicKey()
//verifier, err := spk.NewVerifier()
//if err != nil {
// return err

View File

@@ -61,7 +61,7 @@ func buildSignature(size int) []byte {
func buildFullLeaseSet(n int) LeaseSet {
lease_set_data := make([]byte, 0)
lease_set_data = append(lease_set_data, buildDestination().KeysAndCert.KeyCertificate.RawBytes()...)
lease_set_data = append(lease_set_data, buildDestination().KeysAndCert.keyCertificate.RawBytes()...)
lease_set_data = append(lease_set_data, buildPublicKey()...)
lease_set_data = append(lease_set_data, buildSigningKey()...)
lease_set_data = append(lease_set_data, byte(n))

View File

@@ -2,11 +2,13 @@
package router_address
import (
"encoding/binary"
"errors"
"fmt"
"net"
"strconv"
"strings"
"time"
"github.com/go-i2p/go-i2p/lib/util/logger"
"github.com/sirupsen/logrus"
@@ -359,3 +361,57 @@ func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []b
}
return
}
// NewRouterAddress creates a new RouterAddress with the provided parameters.
// Returns a pointer to RouterAddress.
func NewRouterAddress(cost uint8, expiration time.Time, transportType string, options map[string]string) (*RouterAddress, error) {
log.Debug("Creating new RouterAddress")
// Create TransportCost as an Integer (1 byte)
transportCost, err := NewIntegerFromInt(int(cost), 1)
if err != nil {
log.WithError(err).Error("Failed to create TransportCost Integer")
return nil, err
}
// Create ExpirationDate as a Date
millis := expiration.UnixNano() / int64(time.Millisecond)
dateBytes := make([]byte, DATE_SIZE)
binary.BigEndian.PutUint64(dateBytes, uint64(millis))
expirationDate, _, err := NewDate(dateBytes)
if err != nil {
log.WithError(err).Error("Failed to create ExpirationDate")
return nil, err
}
// Create TransportType as an I2PString
transportTypeStr, err := ToI2PString(transportType)
if err != nil {
log.WithError(err).Error("Failed to create TransportType I2PString")
return nil, err
}
// Create TransportOptions as a Mapping
transportOptions, err := GoMapToMapping(options)
if err != nil {
log.WithError(err).Error("Failed to create TransportOptions Mapping")
return nil, err
}
// Create RouterAddress
ra := &RouterAddress{
TransportCost: transportCost,
ExpirationDate: expirationDate,
TransportType: transportTypeStr,
TransportOptions: transportOptions,
}
log.WithFields(logrus.Fields{
"cost": cost,
"expiration": expiration,
"transportType": transportType,
"options": options,
}).Debug("Successfully created new RouterAddress")
return ra, nil
}

View File

@@ -2,7 +2,10 @@
package router_identity
import (
"github.com/go-i2p/go-i2p/lib/common/certificate"
"github.com/go-i2p/go-i2p/lib/common/key_certificate"
. "github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
"github.com/go-i2p/go-i2p/lib/crypto"
"github.com/go-i2p/go-i2p/lib/util/logger"
"github.com/sirupsen/logrus"
)
@@ -47,3 +50,30 @@ func ReadRouterIdentity(data []byte) (router_identity RouterIdentity, remainder
}).Debug("Successfully read RouterIdentity")
return
}
func NewRouterIdentity(publicKey crypto.PublicKey, signingPublicKey crypto.SigningPublicKey, cert certificate.Certificate, padding []byte) (*RouterIdentity, error) {
log.Debug("Creating new RouterIdentity")
// Step 1: Create keyCertificate from the provided certificate.
// Assuming NewKeyCertificate is a constructor that takes a Certificate and returns a keyCertificate.
keyCert := key_certificate.KeyCertificateFromCertificate(cert)
// Step 2: Create KeysAndCert instance.
keysAndCert, err := NewKeysAndCert(keyCert, publicKey, padding, signingPublicKey)
if err != nil {
log.WithError(err).Error("NewKeysAndCert failed.")
}
// Step 3: Initialize RouterIdentity with KeysAndCert.
routerIdentity := RouterIdentity{
KeysAndCert: *keysAndCert,
}
log.WithFields(logrus.Fields{
"public_key_type": keyCert.PublicKeyType(),
"signing_public_key_type": keyCert.SigningPublicKeyType(),
"padding_length": len(padding),
}).Debug("Successfully created RouterIdentity")
return &routerIdentity, nil
}

View File

@@ -2,9 +2,12 @@
package router_info
import (
"encoding/binary"
"errors"
"github.com/go-i2p/go-i2p/lib/crypto"
"strconv"
"strings"
"time"
"github.com/go-i2p/go-i2p/lib/util/logger"
"github.com/sirupsen/logrus"
@@ -156,7 +159,9 @@ func (router_info *RouterInfo) RouterIdentity() *RouterIdentity {
// IndentHash returns the identity hash (sha256 sum) for this RouterInfo.
func (router_info *RouterInfo) IdentHash() Hash {
log.Debug("Calculating IdentHash for RouterInfo")
data, _ := router_info.RouterIdentity().KeyCertificate.Data()
//data, _ := router_info.RouterIdentity().keyCertificate.Data()
cert := router_info.RouterIdentity().KeysAndCert.Certificate()
data := cert.Data()
hash := HashData(data)
log.WithField("hash", hash).Debug("Calculated IdentHash for RouterInfo")
return HashData(data)
@@ -293,6 +298,118 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
return
}
// serializeWithoutSignature serializes the RouterInfo up to (but not including) the signature.
func (ri *RouterInfo) serializeWithoutSignature() []byte {
var bytes []byte
// Serialize RouterIdentity
bytes = append(bytes, ri.router_identity.Bytes()...)
// Serialize Published Date
bytes = append(bytes, ri.published.Bytes()...)
// Serialize Size
bytes = append(bytes, ri.size.Bytes()...)
// Serialize Addresses
for _, addr := range ri.addresses {
bytes = append(bytes, addr.Bytes()...)
}
// Serialize PeerSize (always zero)
bytes = append(bytes, ri.peer_size.Bytes()...)
// Serialize Options
bytes = append(bytes, ri.options.Data()...)
return bytes
}
func NewRouterInfo(
routerIdentity *RouterIdentity,
publishedTime time.Time,
addresses []*RouterAddress,
options map[string]string,
signingPrivateKey crypto.SigningPrivateKey,
) (*RouterInfo, error) {
log.Debug("Creating new RouterInfo")
// 1. Create Published Date
millis := publishedTime.UnixNano() / int64(time.Millisecond)
dateBytes := make([]byte, DATE_SIZE)
binary.BigEndian.PutUint64(dateBytes, uint64(millis))
publishedDate, _, err := ReadDate(dateBytes)
if err != nil {
log.WithError(err).Error("Failed to create Published Date")
return nil, err
}
// 2. Create Size Integer
sizeInt, err := NewIntegerFromInt(len(addresses), 1)
if err != nil {
log.WithError(err).Error("Failed to create Size Integer")
return nil, err
}
// 3. Create PeerSize Integer (always 0)
peerSizeInt, err := NewIntegerFromInt(0, 1)
if err != nil {
log.WithError(err).Error("Failed to create PeerSize Integer")
return nil, err
}
// 4. Convert options map to Mapping
mapping, err := GoMapToMapping(options)
if err != nil {
log.WithError(err).Error("Failed to convert options map to Mapping")
return nil, err
}
// 5. Assemble RouterInfo without signature
routerInfo := &RouterInfo{
router_identity: *routerIdentity,
published: &publishedDate,
size: sizeInt,
addresses: addresses,
peer_size: peerSizeInt,
options: mapping,
signature: nil, // To be set after signing
}
// 6. Serialize RouterInfo without signature
dataBytes := routerInfo.serializeWithoutSignature()
// 7. Compute signature over serialized data
signer, err := signingPrivateKey.NewSigner()
if err != nil {
log.WithError(err).Error("Failed to create new signer")
return nil, err
}
signatureBytes, err := signer.Sign(dataBytes)
if err != nil {
log.WithError(err).Error("Failed to sign")
}
// 8. Create Signature struct from signatureBytes
sig, _, err := ReadSignature(signatureBytes)
if err != nil {
log.WithError(err).Error("Failed to create Signature from signature bytes")
return nil, err
}
// 9. Attach signature to RouterInfo
routerInfo.signature = &sig
log.WithFields(logrus.Fields{
"router_identity": routerIdentity,
"published": publishedDate,
"address_count": len(addresses),
"options": options,
"signature": sig,
}).Debug("Successfully created RouterInfo")
return routerInfo, nil
}
func (router_info *RouterInfo) RouterCapabilities() string {
log.Debug("Retrieving RouterCapabilities")
str, err := ToI2PString("caps")

View File

@@ -0,0 +1,89 @@
package router_info
import (
"bytes"
"crypto/rand"
"encoding/binary"
"fmt"
"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/router_identity"
"github.com/go-i2p/go-i2p/lib/crypto"
"golang.org/x/crypto/openpgp/elgamal"
"testing"
"time"
)
func TestCreateRouterInfo(t *testing.T) {
// 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.PublicKey = elg_pubkey
// Create KeyCertificate specifying key types
var payload bytes.Buffer
signingPublicKeyType, _ := data.NewIntegerFromInt(7, 2)
cryptoPublicKeyType, _ := data.NewIntegerFromInt(0, 2)
err = binary.Write(&payload, binary.BigEndian, signingPublicKeyType)
if err != nil {
t.Fatalf("Failed to write signing public key type to payload: %v\n", err)
}
err = binary.Write(&payload, binary.BigEndian, cryptoPublicKeyType)
if err != nil {
t.Fatalf("Failed to write crypto public key type to payload: %v\n", err)
}
// 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)
}
// Create RouterIdentity
routerIdentity, err := router_identity.NewRouterIdentity(elg_pubkey, ed25519_pubkey, *cert, nil)
if err != nil {
t.Fatalf("Failed to create router identity: %v\n", err)
}
routerInfo, err := NewRouterInfo(routerIdentity, time.Now(), nil, nil, &ed25519_privkey)
fmt.Printf("routerInfo:%v\n", routerInfo)
}

View File

@@ -2,6 +2,7 @@
package signature
import (
"fmt"
"github.com/go-i2p/go-i2p/lib/util/logger"
"github.com/sirupsen/logrus"
)
@@ -39,30 +40,42 @@ DSA_SHA1. As of release 0.9.12, other types may be supported, depending on conte
// https://geti2p.net/spec/common-structures#signature
type Signature []byte
// ReadSignature returns Signature from a []byte.
// ReadSignature returns a Signature from a []byte.
// The remaining bytes after the specified length are also returned.
// Returns a list of errors that occurred during parsing.
func ReadSignature(bytes []byte) (info Signature, remainder []byte, err error) {
// TODO: stub
log.Warn("ReadSignature is not implemented")
// Returns an error if there is insufficient data to read the signature.
//
// Since the signature type and length are inferred from context (the type of key used),
// and are not explicitly stated, this function assumes the default signature type (DSA_SHA1)
// with a length of 40 bytes.
//
// If a different signature type is expected based on context, this function should be
// modified accordingly to handle the correct signature length.
func ReadSignature(data []byte) (sig Signature, remainder []byte, err error) {
// Assume the default signature type DSA_SHA1 with length 40 bytes
sigLength := DSA_SHA1_SIZE
if len(data) < sigLength {
err = fmt.Errorf("insufficient data to read signature: need %d bytes, have %d", sigLength, len(data))
log.WithError(err).Error("Failed to read Signature")
return
}
sig = data[:sigLength]
remainder = data[sigLength:]
return
}
// NewSignature creates a new *Signature from []byte using ReadSignature.
// Returns a pointer to Signature unlike ReadSignature.
func NewSignature(data []byte) (session_tag *Signature, remainder []byte, err error) {
func NewSignature(data []byte) (signature *Signature, remainder []byte, err error) {
log.WithField("input_length", len(data)).Debug("Creating new Signature")
// sessionTag, remainder, err := ReadSignature(data)
sig, remainder, err := ReadSignature(data)
if err != nil {
log.WithError(err).Error("Failed to read Signature")
return nil, remainder, err
}
session_tag = &sig
signature = &sig
log.WithFields(logrus.Fields{
"signature_length": len(sig),
"remainder_length": len(remainder),
}).Debug("Successfully created new Signature")
return
}

View File

@@ -12,7 +12,10 @@ import (
"github.com/sirupsen/logrus"
)
var Ed25519EncryptTooBig = errors.New("failed to encrypt data, too big for Ed25519")
var (
Ed25519EncryptTooBig = errors.New("failed to encrypt data, too big for Ed25519")
ErrInvalidPublicKeySize = errors.New("failed to verify: invalid ed25519 public key size")
)
type Ed25519PublicKey []byte
@@ -44,22 +47,36 @@ func createEd25519PublicKey(data []byte) (k *ed25519.PublicKey) {
return
}
func createEd25519Encryption(pub *ed25519.PublicKey, rand io.Reader) (enc *Ed25519Encryption, err error) {
/*kbytes := make([]byte, 256)
k := new(big.Int)
for err == nil {
_, err = io.ReadFull(rand, kbytes)
k = new(big.Int).SetBytes(kbytes)
k = k.Mod(k, pub.P)
if k.Sign() != 0 {
break
// createEd25519Encryption initializes the Ed25519Encryption struct using the public key.
func createEd25519Encryption(pub *ed25519.PublicKey, randReader io.Reader) (*Ed25519Encryption, error) {
// Define p = 2^255 - 19
p := new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 255), big.NewInt(19))
// Validate public key length
if len(*pub) != ed25519.PublicKeySize {
log.WithField("pub_length", len(*pub)).Error("Invalid Ed25519 public key size")
return nil, ErrInvalidPublicKeySize
}
// Convert public key bytes to big.Int
a := new(big.Int).SetBytes(*pub)
// Generate a random scalar b1 in [0, p)
b1, err := rand.Int(randReader, p)
if err != nil {
log.WithError(err).Error("Failed to generate b1 for Ed25519Encryption")
return nil, err
}
if err == nil {
enc = &Ed25519Encryption{}
}*/
log.Warn("createEd25519Encryption is not implemented")
return
// Initialize Ed25519Encryption struct
enc := &Ed25519Encryption{
p: p,
a: a,
b1: b1,
}
log.Debug("Ed25519Encryption created successfully")
return enc, nil
}
type Ed25519Encryption struct {
@@ -109,13 +126,18 @@ func (ed25519 *Ed25519Encryption) EncryptPadding(data []byte, zeroPadding bool)
func (elg Ed25519PublicKey) NewEncrypter() (enc Encrypter, err error) {
log.Debug("Creating new Ed25519 encrypter")
k := createEd25519PublicKey(elg[:])
if k == nil {
return nil, errors.New("invalid public key format")
}
enc, err = createEd25519Encryption(k, rand.Reader)
if err != nil {
log.WithError(err).Error("Failed to create Ed25519 encrypter")
} else {
log.Debug("Ed25519 encrypter created successfully")
return nil, err
}
return
log.Debug("Ed25519 encrypter created successfully")
return enc, nil
}
func (v *Ed25519Verifier) VerifyHash(h, sig []byte) (err error) {
@@ -158,6 +180,42 @@ func (v *Ed25519Verifier) Verify(data, sig []byte) (err error) {
type Ed25519PrivateKey ed25519.PrivateKey
func (k Ed25519PrivateKey) NewDecrypter() (Decrypter, error) {
//TODO implement me
panic("implement me")
}
func (k Ed25519PrivateKey) NewSigner() (Signer, error) {
if len(k) != ed25519.PrivateKeySize {
return nil, errors.New("invalid ed25519 private key size")
}
return &Ed25519Signer{k: k}, nil
}
func (k Ed25519PrivateKey) Len() int {
return len(k)
}
func (k *Ed25519PrivateKey) Generate() (SigningPrivateKey, error) {
// Generate a new Ed25519 key pair
_, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
// Assign the generated private key to the receiver
*k = Ed25519PrivateKey(priv)
return k, nil
}
func (k Ed25519PrivateKey) Public() (SigningPublicKey, error) {
if len(k) != ed25519.PrivateKeySize {
return nil, errors.New("invalid ed25519 private key size")
}
// The public key is the first 32 bytes of the private key's seed
pubKey := k[32:]
return Ed25519PublicKey(pubKey), nil
}
type Ed25519Signer struct {
k []byte
}

View File

@@ -27,7 +27,6 @@ type SigningPublicKey interface {
// get the size of this public key
Len() int
}
type PublicKey interface {
Len() int
NewEncrypter() (Encrypter, error)

View File

@@ -53,7 +53,7 @@ func fileRSAPubKey(t *testing.T, filename string) *rsa.PublicKey {
}
var pubKey *rsa.PublicKey
if k, ok := cert.PublicKey.(*rsa.PublicKey); !ok {
t.Fatalf("expected rsa.PublicKey from file %s", filename)
t.Fatalf("expected rsa.publicKey from file %s", filename)
} else {
pubKey = k
}