Work on noise tools, comment details of handshake stuff

This commit is contained in:
eyedeekay
2024-08-25 23:22:21 -04:00
parent a3ce9d36c6
commit 14fc6fc3a8
45 changed files with 237 additions and 162 deletions

View File

@@ -41,7 +41,7 @@ please keep up with these changes, as they will not be backward compatible and r
- [ ] Elligator2 - [ ] Elligator2
- [ ] HKDF - [ ] HKDF
- [ ] HMAC - [ ] HMAC
- [ ] Noise subsystem - [/] Noise subsystem
- End-to-End Crypto - End-to-End Crypto
- [ ] Garlic messages - [ ] Garlic messages
- [ ] ElGamal/AES+SessionTag - [ ] ElGamal/AES+SessionTag

View File

@@ -74,7 +74,7 @@ func TestCertificateDataWhenTooLong(t *testing.T) {
certificate, _, _ := ReadCertificate(bytes) certificate, _, _ := ReadCertificate(bytes)
cert_data := certificate.Data() cert_data := certificate.Data()
cert_len := certificate.Length() //len(cert_data) cert_len := certificate.Length() // len(cert_data)
assert.Equal(cert_len, 2, "certificate.Length() did not return indicated length when data was too long") assert.Equal(cert_len, 2, "certificate.Length() did not return indicated length when data was too long")
if cert_data[0] != 0xff || cert_data[1] != 0xff { if cert_data[0] != 0xff || cert_data[1] != 0xff {
t.Fatal("certificate.Data() returned incorrect data when data was too long") t.Fatal("certificate.Data() returned incorrect data when data was too long")

View File

@@ -29,7 +29,7 @@ func (h Hash) Bytes() [32]byte {
// 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) { func HashData(data []byte) (h Hash) {
//log.Println("Hashing Data:", data) // log.Println("Hashing Data:", data)
h = sha256.Sum256(data) h = sha256.Sum256(data)
return return
} }

View File

@@ -27,7 +27,6 @@ func TestValuesExclusesPairWithBadData(t *testing.T) {
assert.Equal(key, "a", "Values() returned by data with invalid key contains incorrect present key") assert.Equal(key, "a", "Values() returned by data with invalid key contains incorrect present key")
assert.Equal(val, "b", "Values() returned by data with invalid key contains incorrect present key") assert.Equal(val, "b", "Values() returned by data with invalid key contains incorrect present key")
} }
} }
func TestValuesWarnsMissingData(t *testing.T) { func TestValuesWarnsMissingData(t *testing.T) {

View File

@@ -58,9 +58,9 @@ func mappingOrder(values MappingValues) {
// 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.
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) { func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) {
//mapping := remainder // mapping := remainder
//var remainder = mapping // var remainder = mapping
//var err error // var err error
if remainder == nil || len(remainder) < 1 { if remainder == nil || len(remainder) < 1 {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"at": "(Mapping) Values", "at": "(Mapping) Values",
@@ -92,7 +92,7 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
encounteredKeysMap := map[string]bool{} encounteredKeysMap := map[string]bool{}
// pop off length bytes before parsing kv pairs // pop off length bytes before parsing kv pairs
//remainder = remainder[2:] // remainder = remainder[2:]
for { for {
// Read a key, breaking on fatal errors // Read a key, breaking on fatal errors
@@ -116,12 +116,12 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
if err != nil { if err != nil {
if stopValueRead(err) { if stopValueRead(err) {
errs = append(errs, err) errs = append(errs, err)
//return // return
} }
} }
// overwriting remainder with more as another var to prevent memory weirdness in loops // overwriting remainder with more as another var to prevent memory weirdness in loops
remainder = more remainder = more
//log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder) // log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
// Check if key has already been encountered in this mapping // Check if key has already been encountered in this mapping
keyBytes, _ := key_str.Data() keyBytes, _ := key_str.Data()
@@ -160,13 +160,13 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
if err != nil { if err != nil {
if stopValueRead(err) { if stopValueRead(err) {
errs = append(errs, err) errs = append(errs, err)
//return // return
} }
} }
// overwriting remainder with more as another var to prevent memory weirdness in loops // overwriting remainder with more as another var to prevent memory weirdness in loops
remainder = more remainder = more
//log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder) // log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
//log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str) // log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str)
if !beginsWith(remainder, 0x3b) { if !beginsWith(remainder, 0x3b) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"at": "(Mapping) Values", "at": "(Mapping) Values",
@@ -190,5 +190,4 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
} }
values = &map_values values = &map_values
return return
} }

View File

@@ -69,7 +69,7 @@ func (str I2PString) Data() (data string, err error) {
case "string parsing warning: string data is shorter than specified by length": case "string parsing warning: string data is shorter than specified by length":
if is, e := ToI2PString(string(str[:])); e != nil { if is, e := ToI2PString(string(str[:])); e != nil {
return "", e return "", e
}else{ } else {
return is.Data() return is.Data()
} }
case "string parsing warning: string contains data beyond length": case "string parsing warning: string contains data beyond length":

View File

@@ -181,11 +181,11 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
copy(ec_key[KEYCERT_SPK_SIZE:], key_certificate.Certificate.RawBytes()[4:4+extra]) copy(ec_key[KEYCERT_SPK_SIZE:], key_certificate.Certificate.RawBytes()[4:4+extra])
signing_public_key = ec_key signing_public_key = ec_key
case KEYCERT_SIGN_RSA2048: case KEYCERT_SIGN_RSA2048:
//var rsa_key crypto.RSA2048PublicKey // var rsa_key crypto.RSA2048PublicKey
//extra := KEYCERT_SIGN_RSA2048_SIZE - 128 // extra := KEYCERT_SIGN_RSA2048_SIZE - 128
//copy(rsa_key[:], data) // copy(rsa_key[:], data)
//copy(rsa_key[128:], key_certificate[4:4+extra]) // copy(rsa_key[128:], key_certificate[4:4+extra])
//signing_public_key = rsa_key // signing_public_key = rsa_key
case KEYCERT_SIGN_RSA3072: case KEYCERT_SIGN_RSA3072:
case KEYCERT_SIGN_RSA4096: case KEYCERT_SIGN_RSA4096:
case KEYCERT_SIGN_ED25519: case KEYCERT_SIGN_ED25519:

View File

@@ -169,7 +169,7 @@ func (keys_and_cert *KeysAndCert) Certificate() (cert Certificate) {
// Returns a pointer to KeysAndCert unlike ReadKeysAndCert. // Returns a pointer to KeysAndCert unlike ReadKeysAndCert.
func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) { func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) {
data_len := len(data) data_len := len(data)
//keys_and_cert = KeysAndCert{} // keys_and_cert = KeysAndCert{}
if data_len < KEYS_AND_CERT_MIN_SIZE && data_len > KEYS_AND_CERT_DATA_SIZE { if data_len < KEYS_AND_CERT_MIN_SIZE && data_len > KEYS_AND_CERT_DATA_SIZE {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"at": "ReadKeysAndCert", "at": "ReadKeysAndCert",

View File

@@ -172,7 +172,6 @@ func TestNewKeysAndCertWithMissingData(t *testing.T) {
if assert.NotNil(err) { if assert.NotNil(err) {
assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error()) assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error())
} }
} }
func TestNewKeysAndCertWithMissingCertData(t *testing.T) { func TestNewKeysAndCertWithMissingCertData(t *testing.T) {

View File

@@ -77,7 +77,7 @@ func TestDestinationIsCorrect(t *testing.T) {
dest, err := lease_set.Destination() dest, err := lease_set.Destination()
assert.Nil(err) assert.Nil(err)
dest_cert := dest.Certificate() dest_cert := dest.Certificate()
//assert.Nil(err) // assert.Nil(err)
cert_type := dest_cert.Type() cert_type := dest_cert.Type()
assert.Nil(err) assert.Nil(err)
assert.Equal(certificate.CERT_KEY, cert_type) assert.Equal(certificate.CERT_KEY, cert_type)

View File

@@ -185,6 +185,7 @@ func (router_address RouterAddress) IntroducerHashString(num int) I2PString {
v, _ := ToI2PString("ih0") v, _ := ToI2PString("ih0")
return router_address.GetOption(v) return router_address.GetOption(v)
} }
func (router_address RouterAddress) IntroducerExpirationString(num int) I2PString { func (router_address RouterAddress) IntroducerExpirationString(num int) I2PString {
if num >= 0 && num <= 2 { if num >= 0 && num <= 2 {
val := strconv.Itoa(num) val := strconv.Itoa(num)
@@ -194,6 +195,7 @@ func (router_address RouterAddress) IntroducerExpirationString(num int) I2PStrin
v, _ := ToI2PString("iexp0") v, _ := ToI2PString("iexp0")
return router_address.GetOption(v) return router_address.GetOption(v)
} }
func (router_address RouterAddress) IntroducerTagString(num int) I2PString { func (router_address RouterAddress) IntroducerTagString(num int) I2PString {
if num >= 0 && num <= 2 { if num >= 0 && num <= 2 {
val := strconv.Itoa(num) val := strconv.Itoa(num)
@@ -236,7 +238,6 @@ func (router_address RouterAddress) StaticKey() ([32]byte, error) {
return [32]byte{}, fmt.Errorf("error: invalid static key") return [32]byte{}, fmt.Errorf("error: invalid static key")
} }
return [32]byte(sk), nil return [32]byte(sk), nil
} }
func (router_address RouterAddress) InitializationVector() ([32]byte, error) { func (router_address RouterAddress) InitializationVector() ([32]byte, error) {

View File

@@ -31,7 +31,6 @@ func TestCheckRouterAddressValidReportsDataMissing(t *testing.T) {
err, exit := router_address.checkValid() err, exit := router_address.checkValid()
assert.Equal(exit, false, "checkValid indicates to stop parsing when some fields may be present") assert.Equal(exit, false, "checkValid indicates to stop parsing when some fields may be present")
} }
func TestCheckRouterAddressValidNoErrWithValidData(t *testing.T) { func TestCheckRouterAddressValidNoErrWithValidData(t *testing.T) {
@@ -41,7 +40,7 @@ func TestCheckRouterAddressValidNoErrWithValidData(t *testing.T) {
mapping, err := GoMapToMapping(map[string]string{"host": "127.0.0.1", "port": "4567"}) mapping, err := GoMapToMapping(map[string]string{"host": "127.0.0.1", "port": "4567"})
assert.Nil(err, "GoMapToMapping() returned error with valid data") assert.Nil(err, "GoMapToMapping() returned error with valid data")
router_address.TransportOptions = mapping router_address.TransportOptions = mapping
//router_address = append(router_address, mapping...) // router_address = append(router_address, mapping...)
err, exit := router_address.checkValid() err, exit := router_address.checkValid()
assert.Nil(err, "checkValid() reported error with valid data") assert.Nil(err, "checkValid() reported error with valid data")

View File

@@ -15,8 +15,10 @@ import (
const ROUTER_INFO_MIN_SIZE = 439 const ROUTER_INFO_MIN_SIZE = 439
const MIN_GOOD_VERSION = 58 const (
const MAX_GOOD_VERSION = 99 MIN_GOOD_VERSION = 58
MAX_GOOD_VERSION = 99
)
/* /*
[RouterInfo] [RouterInfo]

View File

@@ -131,7 +131,6 @@ func TestRouterAddressesReturnsAddresses(t *testing.T) {
), ),
) )
} }
} }
func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) { func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) {
@@ -162,7 +161,6 @@ func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) {
) )
} }
} }
} }
func TestPeerSizeIsZero(t *testing.T) { func TestPeerSizeIsZero(t *testing.T) {
@@ -200,7 +198,7 @@ func TestRouterIdentityIsCorrect(t *testing.T) {
router_info, _ := buildFullRouterInfo() router_info, _ := buildFullRouterInfo()
router_identity := router_info.RouterIdentity() router_identity := router_info.RouterIdentity()
//assert.Nil(err) // assert.Nil(err)
assert.Equal( assert.Equal(
0, 0,
bytes.Compare( bytes.Compare(

View File

@@ -8,7 +8,6 @@ type Decrypter interface {
} }
type PrivateEncryptionKey interface { type PrivateEncryptionKey interface {
// create a new decryption object for this private key to decrypt data encrypted to our public key // create a new decryption object for this private key to decrypt data encrypted to our public key
// returns decrypter or nil and error if the private key is in a bad format // returns decrypter or nil and error if the private key is in a bad format
NewDecrypter() (Decrypter, error) NewDecrypter() (Decrypter, error)

View File

@@ -2,9 +2,10 @@ package crypto
import ( import (
"crypto/rand" "crypto/rand"
log "github.com/sirupsen/logrus"
"io" "io"
"testing" "testing"
log "github.com/sirupsen/logrus"
) )
func TestDSA(t *testing.T) { func TestDSA(t *testing.T) {

View File

@@ -44,8 +44,10 @@ func createECVerifier(c elliptic.Curve, h crypto.Hash, k []byte) (ev *ECDSAVerif
return return
} }
type ECP256PublicKey [64]byte type (
type ECP256PrivateKey [32]byte ECP256PublicKey [64]byte
ECP256PrivateKey [32]byte
)
func (k ECP256PublicKey) Len() int { func (k ECP256PublicKey) Len() int {
return len(k) return len(k)
@@ -55,8 +57,10 @@ func (k ECP256PublicKey) NewVerifier() (Verifier, error) {
return createECVerifier(elliptic.P256(), crypto.SHA256, k[:]) return createECVerifier(elliptic.P256(), crypto.SHA256, k[:])
} }
type ECP384PublicKey [96]byte type (
type ECP384PrivateKey [48]byte ECP384PublicKey [96]byte
ECP384PrivateKey [48]byte
)
func (k ECP384PublicKey) Len() int { func (k ECP384PublicKey) Len() int {
return len(k) return len(k)
@@ -66,8 +70,10 @@ func (k ECP384PublicKey) NewVerifier() (Verifier, error) {
return createECVerifier(elliptic.P384(), crypto.SHA384, k[:]) return createECVerifier(elliptic.P384(), crypto.SHA384, k[:])
} }
type ECP521PublicKey [132]byte type (
type ECP521PrivateKey [66]byte ECP521PublicKey [132]byte
ECP521PrivateKey [66]byte
)
func (k ECP521PublicKey) Len() int { func (k ECP521PublicKey) Len() int {
return len(k) return len(k)

View File

@@ -30,11 +30,15 @@ var elgp = new(big.Int).SetBytes([]byte{
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}) })
var one = big.NewInt(1) var (
var elgg = big.NewInt(2) one = big.NewInt(1)
elgg = big.NewInt(2)
)
var ElgDecryptFail = errors.New("failed to decrypt elgamal encrypted data") var (
var ElgEncryptTooBig = errors.New("failed to encrypt data, too big for elgamal") ElgDecryptFail = errors.New("failed to decrypt elgamal encrypted data")
ElgEncryptTooBig = errors.New("failed to encrypt data, too big for elgamal")
)
// generate an elgamal key pair // generate an elgamal key pair
func ElgamalGenerate(priv *elgamal.PrivateKey, rand io.Reader) (err error) { func ElgamalGenerate(priv *elgamal.PrivateKey, rand io.Reader) (err error) {
@@ -184,8 +188,10 @@ func createElgamalEncryption(pub *elgamal.PublicKey, rand io.Reader) (enc *Elgam
return return
} }
type ElgPublicKey [256]byte type (
type ElgPrivateKey [256]byte ElgPublicKey [256]byte
ElgPrivateKey [256]byte
)
func (elg ElgPublicKey) Len() int { func (elg ElgPublicKey) Len() int {
return len(elg) return len(elg)

View File

@@ -3,10 +3,11 @@ package crypto
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/openpgp/elgamal"
"io" "io"
"testing" "testing"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/openpgp/elgamal"
) )
func BenchmarkElgGenerate(b *testing.B) { func BenchmarkElgGenerate(b *testing.B) {
@@ -46,7 +47,6 @@ func BenchmarkElgDecrypt(b *testing.B) {
} }
} }
log.Infof("%d fails %d rounds", fails, b.N) log.Infof("%d fails %d rounds", fails, b.N)
} }
func BenchmarkElgEncrypt(b *testing.B) { func BenchmarkElgEncrypt(b *testing.B) {

View File

@@ -8,7 +8,6 @@ type Encrypter interface {
} }
type PublicEncryptionKey interface { type PublicEncryptionKey interface {
// create a new encrypter to encrypt data to this public key // create a new encrypter to encrypt data to this public key
NewEncrypter() (Encrypter, error) NewEncrypter() (Encrypter, error)

View File

@@ -4,11 +4,15 @@ import (
"crypto/md5" "crypto/md5"
) )
const IPAD = byte(0x36) const (
const OPAD = byte(0x5C) IPAD = byte(0x36)
OPAD = byte(0x5C)
)
type HMACKey [32]byte type (
type HMACDigest [16]byte HMACKey [32]byte
HMACDigest [16]byte
)
func (hk HMACKey) xor(p byte) (i []byte) { func (hk HMACKey) xor(p byte) (i []byte) {
i = make([]byte, 64) i = make([]byte, 64)
@@ -25,7 +29,6 @@ func (hk HMACKey) xor(p byte) (i []byte) {
// do i2p hmac // do i2p hmac
func I2PHMAC(data []byte, k HMACKey) (d HMACDigest) { func I2PHMAC(data []byte, k HMACKey) (d HMACDigest) {
buff := make([]byte, 64+len(data)) buff := make([]byte, 64+len(data))
ip := k.xor(IPAD) ip := k.xor(IPAD)
copy(buff, ip) copy(buff, ip)

View File

@@ -1,10 +1,16 @@
package crypto package crypto
type RSA2048PublicKey [256]byte type (
type RSA2048PrivateKey [512]byte RSA2048PublicKey [256]byte
RSA2048PrivateKey [512]byte
)
type RSA3072PublicKey [384]byte type (
type RSA3072PrivateKey [786]byte RSA3072PublicKey [384]byte
RSA3072PrivateKey [786]byte
)
type RSA4096PublicKey [512]byte type (
type RSA4096PrivateKey [1024]byte RSA4096PublicKey [512]byte
RSA4096PrivateKey [1024]byte
)

View File

@@ -4,9 +4,11 @@ import (
"errors" "errors"
) )
var ErrBadSignatureSize = errors.New("bad signature size") var (
var ErrInvalidKeyFormat = errors.New("invalid key format") ErrBadSignatureSize = errors.New("bad signature size")
var ErrInvalidSignature = errors.New("invalid signature") ErrInvalidKeyFormat = errors.New("invalid key format")
ErrInvalidSignature = errors.New("invalid signature")
)
// type for verifying signatures // type for verifying signatures
type Verifier interface { type Verifier interface {

View File

@@ -19,7 +19,6 @@ type Tunnel struct {
} }
func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error) { func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error) {
t = new(Tunnel) t = new(Tunnel)
t.layerKey, err = aes.NewCipher(layerKey[:]) t.layerKey, err = aes.NewCipher(layerKey[:])
if err == nil { if err == nil {

View File

@@ -149,8 +149,10 @@ padding :: Data
total length: 222 total length: 222
*/ */
type BuildRequestRecordElGamalAES [528]byte type (
type BuildRequestRecordElGamal [528]byte BuildRequestRecordElGamalAES [528]byte
BuildRequestRecordElGamal [528]byte
)
type BuildRequestRecord struct { type BuildRequestRecord struct {
ReceiveTunnel tunnel.TunnelID ReceiveTunnel tunnel.TunnelID

View File

@@ -14,7 +14,6 @@ func TestReadBuildRequestRecordReceiveTunnelTooLittleData(t *testing.T) {
receive_tunnel, err := readBuildRequestRecordReceiveTunnel([]byte{0x01}) receive_tunnel, err := readBuildRequestRecordReceiveTunnel([]byte{0x01})
assert.Equal(tunnel.TunnelID(0), receive_tunnel) assert.Equal(tunnel.TunnelID(0), receive_tunnel)
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err) assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
} }
func TestReadBuildRequestRecordReceiveTunnelValidData(t *testing.T) { func TestReadBuildRequestRecordReceiveTunnelValidData(t *testing.T) {

View File

@@ -38,8 +38,10 @@ byte 527 :: reply
total length: 528 total length: 528
*/ */
type BuildResponseRecordELGamalAES [528]byte type (
type BuildResponseRecordELGamal [528]byte BuildResponseRecordELGamalAES [528]byte
BuildResponseRecordELGamal [528]byte
)
type BuildResponseRecord struct { type BuildResponseRecord struct {
Hash common.Hash Hash common.Hash

View File

@@ -61,11 +61,11 @@ func (r Reseed) SingleReseed(uri string) ([]router_info.RouterInfo, error) {
log.Println("warning: this doesn't validate the signature yet", signature) log.Println("warning: this doesn't validate the signature yet", signature)
} }
zip := filepath.Join(config.RouterConfigProperties.NetDb.Path, "reseed.zip") zip := filepath.Join(config.RouterConfigProperties.NetDb.Path, "reseed.zip")
err = os.WriteFile(zip, content, 0644) err = os.WriteFile(zip, content, 0o644)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//content is a zip file, unzip it and get the files // content is a zip file, unzip it and get the files
files, err := unzip.New().Extract(zip, config.RouterConfigProperties.NetDb.Path) files, err := unzip.New().Extract(zip, config.RouterConfigProperties.NetDb.Path)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -154,7 +154,7 @@ func (db *StdNetDB) RecalculateSize() (err error) {
if err == nil { if err == nil {
str := fmt.Sprintf("%d", count) str := fmt.Sprintf("%d", count)
var f *os.File var f *os.File
f, err = os.OpenFile(db.cacheFilePath(), os.O_CREATE|os.O_WRONLY, 0600) f, err = os.OpenFile(db.cacheFilePath(), os.O_CREATE|os.O_WRONLY, 0o600)
if err == nil { if err == nil {
_, err = io.WriteString(f, str) _, err = io.WriteString(f, str)
f.Close() f.Close()
@@ -182,8 +182,8 @@ func (db *StdNetDB) Exists() bool {
func (db *StdNetDB) SaveEntry(e *Entry) (err error) { func (db *StdNetDB) SaveEntry(e *Entry) (err error) {
var f io.WriteCloser var f io.WriteCloser
h := e.RouterInfo.IdentHash() h := e.RouterInfo.IdentHash()
//if err == nil { // if err == nil {
f, err = os.OpenFile(db.SkiplistFile(h), os.O_WRONLY|os.O_CREATE, 0700) f, err = os.OpenFile(db.SkiplistFile(h), os.O_WRONLY|os.O_CREATE, 0o700)
if err == nil { if err == nil {
err = e.WriteTo(f) err = e.WriteTo(f)
f.Close() f.Close()
@@ -224,7 +224,7 @@ func (db *StdNetDB) Ensure() (err error) {
// create base network database directory // create base network database directory
func (db *StdNetDB) Create() (err error) { func (db *StdNetDB) Create() (err error) {
mode := os.FileMode(0700) mode := os.FileMode(0o700)
p := db.Path() p := db.Path()
log.Infof("Create network database in %s", p) log.Infof("Create network database in %s", p)

View File

@@ -146,29 +146,31 @@ var contentTypes = map[byte]ContentType{
0x05: BLOCKLIST, 0x05: BLOCKLIST,
} }
var ErrMissingMagicBytes = errors.New("missing magic bytes") var (
var ErrMissingUnusedByte6 = errors.New("missing unused byte 6") ErrMissingMagicBytes = errors.New("missing magic bytes")
var ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version") ErrMissingUnusedByte6 = errors.New("missing unused byte 6")
var ErrMissingSignatureType = errors.New("missing or invalid signature type") ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version")
var ErrUnsupportedSignatureType = errors.New("unsupported signature type") ErrMissingSignatureType = errors.New("missing or invalid signature type")
var ErrMissingSignatureLength = errors.New("missing signature length") ErrUnsupportedSignatureType = errors.New("unsupported signature type")
var ErrMissingUnusedByte12 = errors.New("missing unused byte 12") ErrMissingSignatureLength = errors.New("missing signature length")
var ErrMissingVersionLength = errors.New("missing version length") ErrMissingUnusedByte12 = errors.New("missing unused byte 12")
var ErrVersionTooShort = errors.New("version length too short") ErrMissingVersionLength = errors.New("missing version length")
var ErrMissingUnusedByte14 = errors.New("missing unused byte 14") ErrVersionTooShort = errors.New("version length too short")
var ErrMissingSignerIDLength = errors.New("missing signer ID length") ErrMissingUnusedByte14 = errors.New("missing unused byte 14")
var ErrMissingContentLength = errors.New("missing content length") ErrMissingSignerIDLength = errors.New("missing signer ID length")
var ErrMissingUnusedByte24 = errors.New("missing unused byte 24") ErrMissingContentLength = errors.New("missing content length")
var ErrMissingFileType = errors.New("missing or invalid file type") ErrMissingUnusedByte24 = errors.New("missing unused byte 24")
var ErrMissingUnusedByte26 = errors.New("missing unused byte 26") ErrMissingFileType = errors.New("missing or invalid file type")
var ErrMissingContentType = errors.New("missing or invalid content type") ErrMissingUnusedByte26 = errors.New("missing unused byte 26")
var ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39") ErrMissingContentType = errors.New("missing or invalid content type")
var ErrMissingVersion = errors.New("missing version") ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39")
var ErrMissingSignerID = errors.New("missing signer ID") ErrMissingVersion = errors.New("missing version")
var ErrMissingContent = errors.New("missing content") ErrMissingSignerID = errors.New("missing signer ID")
var ErrMissingSignature = errors.New("missing signature") ErrMissingContent = errors.New("missing content")
var ErrInvalidPublicKey = errors.New("invalid public key") ErrMissingSignature = errors.New("missing signature")
var ErrInvalidSignature = errors.New("invalid signature") ErrInvalidPublicKey = errors.New("invalid public key")
ErrInvalidSignature = errors.New("invalid signature")
)
const magicBytes = "I2Psu3" const magicBytes = "I2Psu3"

View File

@@ -9,11 +9,12 @@ import (
"encoding/binary" "encoding/binary"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"github.com/stretchr/testify/assert"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
func fileReader(t *testing.T, filename string) io.Reader { func fileReader(t *testing.T, filename string) io.Reader {
@@ -60,11 +61,13 @@ func fileRSAPubKey(t *testing.T, filename string) *rsa.PublicKey {
} }
// This fake data is generated in TestMain. // This fake data is generated in TestMain.
var aliceFakeKey *rsa.PrivateKey var (
var bobFakeKey *rsa.PrivateKey aliceFakeKey *rsa.PrivateKey
var aliceContent []byte bobFakeKey *rsa.PrivateKey
var aliceSignature []byte aliceContent []byte
var aliceSU3 []byte aliceSignature []byte
aliceSU3 []byte
)
func TestRead(t *testing.T) { func TestRead(t *testing.T) {
tests := []struct { tests := []struct {

View File

@@ -46,10 +46,12 @@ package ntcp
type MessageType uint8 type MessageType uint8
const MessageTypeSessionRequest = 0x00 const (
const MessageTypeSessionCreated = 0x01 MessageTypeSessionRequest = 0x00
const MessageTypeSessionConfirmed = 0x02 MessageTypeSessionCreated = 0x01
const MessageTypeData = 0x03 MessageTypeSessionConfirmed = 0x02
MessageTypeData = 0x03
)
type Message interface { type Message interface {
// Type returns the message type // Type returns the message type

View File

@@ -10,7 +10,7 @@ import (
) )
// wrapper around flynn/noise with just enough options exposed to enable configuring NTCP2 // wrapper around flynn/noise with just enough options exposed to enable configuring NTCP2
// possible and/or relatively intuitive
type Noise struct { type Noise struct {
noise.Config noise.Config
router_address.RouterAddress // always the local addr router_address.RouterAddress // always the local addr
@@ -42,10 +42,11 @@ func (ns *Noise) lockMutex() {
} }
} }
var ex_ns net.Conn = &NoiseConn{} var (
var ex_ns_l net.Listener = &NoiseListener{} ex_ns net.Conn = &NoiseConn{}
var ex_ns_u net.PacketConn = &NoisePacketConn{} ex_ns_l net.Listener = &NoiseListener{}
//var ex_tc_up net.PacketConn = &NoiseConn{} ex_ns_u net.PacketConn = &NoisePacketConn{}
)
func NewNoise(ra router_address.RouterAddress) (ns *Noise, err error) { func NewNoise(ra router_address.RouterAddress) (ns *Noise, err error) {
ns = &Noise{} ns = &Noise{}
@@ -53,8 +54,10 @@ func NewNoise(ra router_address.RouterAddress) (ns *Noise, err error) {
ns.Config = noise.Config{ ns.Config = noise.Config{
CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256), CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256),
Pattern: noise.HandshakeXK, Pattern: noise.HandshakeXK,
//StaticKeypair: , // here's the sort of tricky/undefined part. The NTCP2 spec says we need to be able to obfuscate and deobfuscate these static keys before we give them to noise.
//EphemeralKeypair: , // pretty sure that's no biggie but designing it has been... wierd? probably overthinking it.
// StaticKeypair: ,
// EphemeralKeypair: ,
} }
return return
} }
@@ -67,35 +70,60 @@ func (ns *Noise) Addr() net.Addr {
return ns.LocalAddr() return ns.LocalAddr()
} }
func (ns *Noise) DialNoise(addr router_address.RouterAddress) (conn NoiseConn, err error) { func (ns *Noise) DialNoise(addr router_address.RouterAddress) (conn net.Conn, err error) {
cfg := ns cfg := ns
cfg.Initiator = false cfg.Initiator = false
network := "tcp" network := "tcp"
var host net.Addr
var port string
if ns.UDP() { if ns.UDP() {
network = "udp" network = "udp"
host, err = ns.RouterAddress.Host()
if err != nil {
return
}
port, err = ns.RouterAddress.Port()
if err != nil {
return
}
raddr := net.JoinHostPort(host.String(), port)
var netConn net.Conn
netConn, err = net.Dial(network, raddr)
if err != nil {
return
}
cfg.HandshakeState, err = noise.NewHandshakeState(cfg.Config)
if err != nil {
return
}
return &NoisePacketConn{
Noise: cfg,
Conn: netConn,
}, nil
} else {
host, err = ns.RouterAddress.Host()
if err != nil {
return
}
port, err = ns.RouterAddress.Port()
if err != nil {
return
}
raddr := net.JoinHostPort(host.String(), port)
var netConn net.Conn
netConn, err = net.Dial(network, raddr)
if err != nil {
return
}
cfg.HandshakeState, err = noise.NewHandshakeState(cfg.Config)
if err != nil {
return
}
return &NoiseConn{
Noise: cfg,
Conn: netConn,
}, nil
} }
host, err := ns.RouterAddress.Host()
if err != nil {
return
}
port, err := ns.RouterAddress.Port()
if err != nil {
return
}
raddr := net.JoinHostPort(host.String(), port)
netConn, err := net.Dial(network, raddr)
if err != nil {
return
}
hs, err := noise.NewHandshakeState(cfg.Config)
if err != nil {
return
}
cfg.HandshakeState = hs
return NoiseConn{
Noise: cfg,
Conn: netConn,
}, nil
} }
func (ns *Noise) ListenNoise() (list NoiseListener, err error) { func (ns *Noise) ListenNoise() (list NoiseListener, err error) {
@@ -111,7 +139,7 @@ func (ns *Noise) ListenNoise() (list NoiseListener, err error) {
return return
} }
portNum, _ := strconv.Atoi(port) portNum, _ := strconv.Atoi(port)
port = strconv.Itoa(portNum+1) port = strconv.Itoa(portNum + 1)
hostip := net.JoinHostPort(host.String(), port) hostip := net.JoinHostPort(host.String(), port)
listener, err := net.Listen(network, hostip) listener, err := net.Listen(network, hostip)
if err != nil { if err != nil {

View File

@@ -27,23 +27,29 @@ func (nc *NoiseConn) LocalAddr() net.Addr {
// Write implements net.Conn. // Write implements net.Conn.
func (nc *NoiseConn) Write(b []byte) (n int, err error) { func (nc *NoiseConn) Write(b []byte) (n int, err error) {
nc.lockMutex() nc.lockMutex()
if nc.HandshakeState == nil { if nc.HandshakeState != nil {
nc.unlockMutex()
} else {
defer nc.unlockMutex() defer nc.unlockMutex()
for nc.HandshakeState != nil && len(b) > 0 { for nc.HandshakeState != nil && len(b) > 0 {
if !nc.Initiator { if !nc.Initiator {
// If we're the initiator, then we set that in advance and we already know.
// If not, we need to read the handshake state first.
err = nc.HandshakeStateRead() err = nc.HandshakeStateRead()
if err != nil { if err != nil {
return n, err return n, err
} }
} }
// if the HandshakeState is not populated here we are the initiator.
// we could(should? shouldn't?) check both but for now I'm sticking with what
// NoiseConn does
if nc.HandshakeState != nil { if nc.HandshakeState != nil {
// choose either the length of b or the maximum length of a message
l := min(noise.MaxMsgLen, len(b)) l := min(noise.MaxMsgLen, len(b))
// update the HandshakeState using l number of bytes to the write message buffer
nc.writeMsgBuf, err = nc.HandshakeStateCreate(nc.writeMsgBuf[:0], b[:l]) nc.writeMsgBuf, err = nc.HandshakeStateCreate(nc.writeMsgBuf[:0], b[:l])
if err != nil { if err != nil {
return n, err return n, err
} }
// write the message buffer to the socket
_, err = nc.Conn.Write(nc.writeMsgBuf) _, err = nc.Conn.Write(nc.writeMsgBuf)
if err != nil { if err != nil {
return n, err return n, err
@@ -54,6 +60,7 @@ func (nc *NoiseConn) Write(b []byte) (n int, err error) {
} }
} }
nc.unlockMutex() nc.unlockMutex()
// zero-out the write buffer
nc.writeMsgBuf = nc.writeMsgBuf[:0] nc.writeMsgBuf = nc.writeMsgBuf[:0]
for len(b) > 0 { for len(b) > 0 {
outlen := len(nc.writeMsgBuf) outlen := len(nc.writeMsgBuf)
@@ -76,7 +83,6 @@ func (nc *NoiseConn) Write(b []byte) (n int, err error) {
nc.writeMsgBuf = nc.writeMsgBuf[:0] nc.writeMsgBuf = nc.writeMsgBuf[:0]
} }
} }
if len(nc.writeMsgBuf) > 0 { if len(nc.writeMsgBuf) > 0 {
_, err = nc.Conn.Write(nc.writeMsgBuf) _, err = nc.Conn.Write(nc.writeMsgBuf)
if err != nil { if err != nil {

View File

@@ -2,6 +2,8 @@ package noise
import "github.com/flynn/noise" import "github.com/flynn/noise"
// HandshakeStateRead reads a handshake's state off the socket for storage in the
// NoiseConn.HandshakeState
func (nc *NoiseConn) HandshakeStateRead() (err error) { func (nc *NoiseConn) HandshakeStateRead() (err error) {
nc.readMsgBuf, err = nc.ReadMsg(nc.readMsgBuf[:0]) nc.readMsgBuf, err = nc.ReadMsg(nc.readMsgBuf[:0])
if err != nil { if err != nil {
@@ -35,7 +37,7 @@ func (nc *NoiseConn) HandshakeStateCreate(out, payload []byte) (by []byte, err e
//} //}
nc.SetCipherStates(cs1, cs2) nc.SetCipherStates(cs1, cs2)
nc.HandshakeStateResponsibility = false nc.HandshakeStateResponsibility = false
//nc.readBarrier.Release() // nc.readBarrier.Release()
return out, nc.Frame(out[outlen:], out[outlen+4:]) return out, nc.Frame(out[outlen:], out[outlen+4:])
} }
@@ -54,7 +56,7 @@ func (nc *NoiseConn) SetCipherStates(cs1, cs2 *noise.CipherState) {
nc.send, nc.recv = cs2, cs1 nc.send, nc.recv = cs2, cs1
} }
if nc.send != nil { if nc.send != nil {
//nc.readBarrier.Release() // nc.readBarrier.Release()
nc.handshakeHash = nc.HandshakeState.ChannelBinding() nc.handshakeHash = nc.HandshakeState.ChannelBinding()
nc.HandshakeState = nil nc.HandshakeState = nil
} }

View File

@@ -7,13 +7,29 @@ import (
type NoisePacketConn struct { type NoisePacketConn struct {
*Noise *Noise
net.PacketConn // this is always a actually a PacketConn
net.Conn
}
// Read implements net.Conn.
func (*NoisePacketConn) Read(b []byte) (n int, err error) {
panic("unimplemented")
}
// RemoteAddr implements net.Conn.
func (n *NoisePacketConn) RemoteAddr() net.Addr {
panic("unimplemented")
}
// Write implements net.Conn.
func (*NoisePacketConn) Write(b []byte) (n int, err error) {
panic("unimplemented")
} }
// Close implements net.PacketConn. // Close implements net.PacketConn.
// Subtle: this method shadows the method (PacketConn).Close of NoisePacketConn.PacketConn. // Subtle: this method shadows the method (Conn).Close of NoisePacketConn.Conn.
func (n *NoisePacketConn) Close() error { func (n *NoisePacketConn) Close() error {
return n.PacketConn.Close() return n.Conn.Close()
} }
// LocalAddr implements net.PacketConn. // LocalAddr implements net.PacketConn.

View File

@@ -2,5 +2,4 @@ package ntcp
// Session implements TransportSession // Session implements TransportSession
// An established transport session // An established transport session
type Session struct { type Session struct{}
}

View File

@@ -11,5 +11,4 @@ const (
) )
// Transport is an ntcp transport implementing transport.Transport interface // Transport is an ntcp transport implementing transport.Transport interface
type Transport struct { type Transport struct{}
}

View File

@@ -708,6 +708,7 @@ func maybeAppendDelay(di_flag DeliveryInstructions, data, current []byte) (now [
} }
return return
} }
func maybeAppendMessageID(di_flag DeliveryInstructions, di_type int, data, current []byte) (now []byte, err error) { func maybeAppendMessageID(di_flag DeliveryInstructions, di_type int, data, current []byte) (now []byte, err error) {
if di_type == FIRST_FRAGMENT { if di_type == FIRST_FRAGMENT {
if fragmented, _ := di_flag.Fragmented(); fragmented { if fragmented, _ := di_flag.Fragmented(); fragmented {

View File

@@ -2,6 +2,7 @@ package tunnel
import ( import (
"encoding/binary" "encoding/binary"
"github.com/go-i2p/go-i2p/lib/crypto" "github.com/go-i2p/go-i2p/lib/crypto"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )

View File

@@ -1,8 +1,9 @@
package tunnel package tunnel
import ( import (
"github.com/stretchr/testify/assert"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
func TestDeliveryInstructionDataWithNoPadding(t *testing.T) { func TestDeliveryInstructionDataWithNoPadding(t *testing.T) {
@@ -33,7 +34,6 @@ func TestDeliveryInstructionDataWithSomePadding(t *testing.T) {
copy(decrypted_tunnel_message[:], data) copy(decrypted_tunnel_message[:], data)
di := decrypted_tunnel_message.deliveryInstructionData() di := decrypted_tunnel_message.deliveryInstructionData()
assert.Equal(1028-4-4-16-1-padding_size, len(di)) assert.Equal(1028-4-4-16-1-padding_size, len(di))
} }
func TestDeliveryInstructionDataWithOnlyPadding(t *testing.T) { func TestDeliveryInstructionDataWithOnlyPadding(t *testing.T) {
@@ -53,11 +53,9 @@ func TestDeliveryInstructionDataWithOnlyPadding(t *testing.T) {
} }
func TestDeliveryInstructionsWithFragmentsWithAllPadding(t *testing.T) { func TestDeliveryInstructionsWithFragmentsWithAllPadding(t *testing.T) {
} }
// Test invalid delivery instructions and message fragments // Test invalid delivery instructions and message fragments
func TestDeliveryInstructionsWithFragmentsWithValidData(t *testing.T) { func TestDeliveryInstructionsWithFragmentsWithValidData(t *testing.T) {
} }

View File

@@ -1,5 +1,4 @@
package tunnel package tunnel
// a pool of tunnels which we have created // a pool of tunnels which we have created
type Pool struct { type Pool struct{}
}

View File

@@ -27,5 +27,4 @@ func Handle() {
// wtf? // wtf?
} }
} }
} }

View File

@@ -25,5 +25,4 @@ func Handle() {
// wtf? // wtf?
} }
} }
} }

View File

@@ -1,12 +1,12 @@
package main package main
import ( import (
"flag"
"github.com/go-i2p/go-i2p/lib/config" "github.com/go-i2p/go-i2p/lib/config"
"github.com/go-i2p/go-i2p/lib/router" "github.com/go-i2p/go-i2p/lib/router"
"github.com/go-i2p/go-i2p/lib/util/signals" "github.com/go-i2p/go-i2p/lib/util/signals"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"flag"
) )
func main() { func main() {