From 14fc6fc3a87c9da646245776e464adc50c5b5da0 Mon Sep 17 00:00:00 2001 From: eyedeekay Date: Sun, 25 Aug 2024 23:22:21 -0400 Subject: [PATCH] Work on noise tools, comment details of handshake stuff --- README.md | 2 +- lib/common/certificate/certificate_test.go | 2 +- lib/common/data/hash.go | 2 +- lib/common/data/mapping_test.go | 1 - lib/common/data/mapping_values.go | 19 ++-- lib/common/data/string.go | 2 +- lib/common/key_certificate/key_certificate.go | 10 +-- lib/common/keys_and_cert/keys_and_cert.go | 2 +- .../keys_and_cert/keys_and_cert_test.go | 1 - lib/common/lease_set/lease_set_test.go | 2 +- lib/common/router_address/router_address.go | 3 +- .../router_address/router_address_test.go | 3 +- lib/common/router_info/router_info.go | 6 +- lib/common/router_info/router_info_test.go | 4 +- lib/crypto/decrypt.go | 1 - lib/crypto/dsa_test.go | 3 +- lib/crypto/ecdsa.go | 18 ++-- lib/crypto/elg.go | 18 ++-- lib/crypto/elg_test.go | 6 +- lib/crypto/encrypt.go | 1 - lib/crypto/hmac.go | 13 +-- lib/crypto/rsa.go | 18 ++-- lib/crypto/sign.go | 8 +- lib/crypto/tunnel.go | 1 - lib/i2np/build_request_record.go | 6 +- lib/i2np/build_request_record_test.go | 1 - lib/i2np/build_response_record.go | 6 +- lib/netdb/reseed/reseed.go | 4 +- lib/netdb/std.go | 8 +- lib/su3/su3.go | 48 +++++----- lib/su3/su3_test.go | 15 ++-- lib/transport/messages/message.go | 10 ++- lib/transport/noise/noise.go | 90 ++++++++++++------- lib/transport/noise/noise_conn.go | 14 ++- lib/transport/noise/noise_conn_util.go | 6 +- lib/transport/noise/noise_packetconn.go | 22 ++++- lib/transport/ntcp/session.go | 3 +- lib/transport/ntcp/transport.go | 3 +- lib/tunnel/delivery.go | 1 + lib/tunnel/message.go | 1 + lib/tunnel/message_test.go | 6 +- lib/tunnel/pool.go | 3 +- lib/util/signals/unix.go | 1 - lib/util/signals/windows.go | 1 - main.go | 4 +- 45 files changed, 237 insertions(+), 162 deletions(-) diff --git a/README.md b/README.md index b587d3a..9595fb1 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ please keep up with these changes, as they will not be backward compatible and r - [ ] Elligator2 - [ ] HKDF - [ ] HMAC - - [ ] Noise subsystem + - [/] Noise subsystem - End-to-End Crypto - [ ] Garlic messages - [ ] ElGamal/AES+SessionTag diff --git a/lib/common/certificate/certificate_test.go b/lib/common/certificate/certificate_test.go index 3fe6de2..dee3653 100644 --- a/lib/common/certificate/certificate_test.go +++ b/lib/common/certificate/certificate_test.go @@ -74,7 +74,7 @@ func TestCertificateDataWhenTooLong(t *testing.T) { certificate, _, _ := ReadCertificate(bytes) 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") if cert_data[0] != 0xff || cert_data[1] != 0xff { t.Fatal("certificate.Data() returned incorrect data when data was too long") diff --git a/lib/common/data/hash.go b/lib/common/data/hash.go index fa130d7..d50f4e9 100644 --- a/lib/common/data/hash.go +++ b/lib/common/data/hash.go @@ -29,7 +29,7 @@ func (h Hash) Bytes() [32]byte { // HashData returns the SHA256 sum of a []byte input as Hash. func HashData(data []byte) (h Hash) { - //log.Println("Hashing Data:", data) + // log.Println("Hashing Data:", data) h = sha256.Sum256(data) return } diff --git a/lib/common/data/mapping_test.go b/lib/common/data/mapping_test.go index 986d2bd..563f575 100644 --- a/lib/common/data/mapping_test.go +++ b/lib/common/data/mapping_test.go @@ -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(val, "b", "Values() returned by data with invalid key contains incorrect present key") } - } func TestValuesWarnsMissingData(t *testing.T) { diff --git a/lib/common/data/mapping_values.go b/lib/common/data/mapping_values.go index f6d8ce7..0c4f6c4 100644 --- a/lib/common/data/mapping_values.go +++ b/lib/common/data/mapping_values.go @@ -58,9 +58,9 @@ func mappingOrder(values MappingValues) { // The remaining bytes after the specified length are also returned. // Returns a list of errors that occurred during parsing. func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) { - //mapping := remainder - //var remainder = mapping - //var err error + // mapping := remainder + // var remainder = mapping + // var err error if remainder == nil || len(remainder) < 1 { log.WithFields(log.Fields{ "at": "(Mapping) Values", @@ -92,7 +92,7 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal encounteredKeysMap := map[string]bool{} // pop off length bytes before parsing kv pairs - //remainder = remainder[2:] + // remainder = remainder[2:] for { // Read a key, breaking on fatal errors @@ -116,12 +116,12 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal if err != nil { if stopValueRead(err) { errs = append(errs, err) - //return + // return } } // overwriting remainder with more as another var to prevent memory weirdness in loops 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 keyBytes, _ := key_str.Data() @@ -160,13 +160,13 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal if err != nil { if stopValueRead(err) { errs = append(errs, err) - //return + // return } } // overwriting remainder with more as another var to prevent memory weirdness in loops remainder = more - //log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder) - //log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str) + // log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder) + // log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str) if !beginsWith(remainder, 0x3b) { log.WithFields(log.Fields{ "at": "(Mapping) Values", @@ -190,5 +190,4 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal } values = &map_values return - } diff --git a/lib/common/data/string.go b/lib/common/data/string.go index fe9f0d9..8b28c83 100644 --- a/lib/common/data/string.go +++ b/lib/common/data/string.go @@ -69,7 +69,7 @@ func (str I2PString) Data() (data string, err error) { case "string parsing warning: string data is shorter than specified by length": if is, e := ToI2PString(string(str[:])); e != nil { return "", e - }else{ + } else { return is.Data() } case "string parsing warning: string contains data beyond length": diff --git a/lib/common/key_certificate/key_certificate.go b/lib/common/key_certificate/key_certificate.go index 22aaba8..a8b761e 100644 --- a/lib/common/key_certificate/key_certificate.go +++ b/lib/common/key_certificate/key_certificate.go @@ -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]) signing_public_key = ec_key case KEYCERT_SIGN_RSA2048: - //var rsa_key crypto.RSA2048PublicKey - //extra := KEYCERT_SIGN_RSA2048_SIZE - 128 - //copy(rsa_key[:], data) - //copy(rsa_key[128:], key_certificate[4:4+extra]) - //signing_public_key = rsa_key + // var rsa_key crypto.RSA2048PublicKey + // extra := KEYCERT_SIGN_RSA2048_SIZE - 128 + // copy(rsa_key[:], data) + // copy(rsa_key[128:], key_certificate[4:4+extra]) + // signing_public_key = rsa_key case KEYCERT_SIGN_RSA3072: case KEYCERT_SIGN_RSA4096: case KEYCERT_SIGN_ED25519: diff --git a/lib/common/keys_and_cert/keys_and_cert.go b/lib/common/keys_and_cert/keys_and_cert.go index f6e9e52..0ab5465 100644 --- a/lib/common/keys_and_cert/keys_and_cert.go +++ b/lib/common/keys_and_cert/keys_and_cert.go @@ -169,7 +169,7 @@ func (keys_and_cert *KeysAndCert) Certificate() (cert Certificate) { // Returns a pointer to KeysAndCert unlike ReadKeysAndCert. func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) { 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 { log.WithFields(log.Fields{ "at": "ReadKeysAndCert", diff --git a/lib/common/keys_and_cert/keys_and_cert_test.go b/lib/common/keys_and_cert/keys_and_cert_test.go index b3a141e..f24ea93 100644 --- a/lib/common/keys_and_cert/keys_and_cert_test.go +++ b/lib/common/keys_and_cert/keys_and_cert_test.go @@ -172,7 +172,6 @@ func TestNewKeysAndCertWithMissingData(t *testing.T) { if assert.NotNil(err) { assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error()) } - } func TestNewKeysAndCertWithMissingCertData(t *testing.T) { diff --git a/lib/common/lease_set/lease_set_test.go b/lib/common/lease_set/lease_set_test.go index 8c29ca6..7851fcd 100644 --- a/lib/common/lease_set/lease_set_test.go +++ b/lib/common/lease_set/lease_set_test.go @@ -77,7 +77,7 @@ func TestDestinationIsCorrect(t *testing.T) { dest, err := lease_set.Destination() assert.Nil(err) dest_cert := dest.Certificate() - //assert.Nil(err) + // assert.Nil(err) cert_type := dest_cert.Type() assert.Nil(err) assert.Equal(certificate.CERT_KEY, cert_type) diff --git a/lib/common/router_address/router_address.go b/lib/common/router_address/router_address.go index 32740b2..b735e95 100644 --- a/lib/common/router_address/router_address.go +++ b/lib/common/router_address/router_address.go @@ -185,6 +185,7 @@ func (router_address RouterAddress) IntroducerHashString(num int) I2PString { v, _ := ToI2PString("ih0") return router_address.GetOption(v) } + func (router_address RouterAddress) IntroducerExpirationString(num int) I2PString { if num >= 0 && num <= 2 { val := strconv.Itoa(num) @@ -194,6 +195,7 @@ func (router_address RouterAddress) IntroducerExpirationString(num int) I2PStrin v, _ := ToI2PString("iexp0") return router_address.GetOption(v) } + func (router_address RouterAddress) IntroducerTagString(num int) I2PString { if num >= 0 && num <= 2 { 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(sk), nil - } func (router_address RouterAddress) InitializationVector() ([32]byte, error) { diff --git a/lib/common/router_address/router_address_test.go b/lib/common/router_address/router_address_test.go index a65d29c..153f83b 100644 --- a/lib/common/router_address/router_address_test.go +++ b/lib/common/router_address/router_address_test.go @@ -31,7 +31,6 @@ func TestCheckRouterAddressValidReportsDataMissing(t *testing.T) { err, exit := router_address.checkValid() assert.Equal(exit, false, "checkValid indicates to stop parsing when some fields may be present") - } 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"}) assert.Nil(err, "GoMapToMapping() returned error with valid data") router_address.TransportOptions = mapping - //router_address = append(router_address, mapping...) + // router_address = append(router_address, mapping...) err, exit := router_address.checkValid() assert.Nil(err, "checkValid() reported error with valid data") diff --git a/lib/common/router_info/router_info.go b/lib/common/router_info/router_info.go index 6fd0a35..49cfaf2 100644 --- a/lib/common/router_info/router_info.go +++ b/lib/common/router_info/router_info.go @@ -15,8 +15,10 @@ import ( const ROUTER_INFO_MIN_SIZE = 439 -const MIN_GOOD_VERSION = 58 -const MAX_GOOD_VERSION = 99 +const ( + MIN_GOOD_VERSION = 58 + MAX_GOOD_VERSION = 99 +) /* [RouterInfo] diff --git a/lib/common/router_info/router_info_test.go b/lib/common/router_info/router_info_test.go index 4aeb2e7..11fb4c4 100644 --- a/lib/common/router_info/router_info_test.go +++ b/lib/common/router_info/router_info_test.go @@ -131,7 +131,6 @@ func TestRouterAddressesReturnsAddresses(t *testing.T) { ), ) } - } func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) { @@ -162,7 +161,6 @@ func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) { ) } } - } func TestPeerSizeIsZero(t *testing.T) { @@ -200,7 +198,7 @@ func TestRouterIdentityIsCorrect(t *testing.T) { router_info, _ := buildFullRouterInfo() router_identity := router_info.RouterIdentity() - //assert.Nil(err) + // assert.Nil(err) assert.Equal( 0, bytes.Compare( diff --git a/lib/crypto/decrypt.go b/lib/crypto/decrypt.go index a22f32d..a3fd616 100644 --- a/lib/crypto/decrypt.go +++ b/lib/crypto/decrypt.go @@ -8,7 +8,6 @@ type Decrypter interface { } type PrivateEncryptionKey interface { - // 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 NewDecrypter() (Decrypter, error) diff --git a/lib/crypto/dsa_test.go b/lib/crypto/dsa_test.go index 453048a..5ca8967 100644 --- a/lib/crypto/dsa_test.go +++ b/lib/crypto/dsa_test.go @@ -2,9 +2,10 @@ package crypto import ( "crypto/rand" - log "github.com/sirupsen/logrus" "io" "testing" + + log "github.com/sirupsen/logrus" ) func TestDSA(t *testing.T) { diff --git a/lib/crypto/ecdsa.go b/lib/crypto/ecdsa.go index feadedf..1e76e0f 100644 --- a/lib/crypto/ecdsa.go +++ b/lib/crypto/ecdsa.go @@ -44,8 +44,10 @@ func createECVerifier(c elliptic.Curve, h crypto.Hash, k []byte) (ev *ECDSAVerif return } -type ECP256PublicKey [64]byte -type ECP256PrivateKey [32]byte +type ( + ECP256PublicKey [64]byte + ECP256PrivateKey [32]byte +) func (k ECP256PublicKey) Len() int { return len(k) @@ -55,8 +57,10 @@ func (k ECP256PublicKey) NewVerifier() (Verifier, error) { return createECVerifier(elliptic.P256(), crypto.SHA256, k[:]) } -type ECP384PublicKey [96]byte -type ECP384PrivateKey [48]byte +type ( + ECP384PublicKey [96]byte + ECP384PrivateKey [48]byte +) func (k ECP384PublicKey) Len() int { return len(k) @@ -66,8 +70,10 @@ func (k ECP384PublicKey) NewVerifier() (Verifier, error) { return createECVerifier(elliptic.P384(), crypto.SHA384, k[:]) } -type ECP521PublicKey [132]byte -type ECP521PrivateKey [66]byte +type ( + ECP521PublicKey [132]byte + ECP521PrivateKey [66]byte +) func (k ECP521PublicKey) Len() int { return len(k) diff --git a/lib/crypto/elg.go b/lib/crypto/elg.go index 1174a2c..853f37d 100644 --- a/lib/crypto/elg.go +++ b/lib/crypto/elg.go @@ -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, }) -var one = big.NewInt(1) -var elgg = big.NewInt(2) +var ( + one = big.NewInt(1) + elgg = big.NewInt(2) +) -var ElgDecryptFail = errors.New("failed to decrypt elgamal encrypted data") -var ElgEncryptTooBig = errors.New("failed to encrypt data, too big for elgamal") +var ( + 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 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 } -type ElgPublicKey [256]byte -type ElgPrivateKey [256]byte +type ( + ElgPublicKey [256]byte + ElgPrivateKey [256]byte +) func (elg ElgPublicKey) Len() int { return len(elg) diff --git a/lib/crypto/elg_test.go b/lib/crypto/elg_test.go index 58cef06..36b7c0e 100644 --- a/lib/crypto/elg_test.go +++ b/lib/crypto/elg_test.go @@ -3,10 +3,11 @@ package crypto import ( "bytes" "crypto/rand" - log "github.com/sirupsen/logrus" - "golang.org/x/crypto/openpgp/elgamal" "io" "testing" + + log "github.com/sirupsen/logrus" + "golang.org/x/crypto/openpgp/elgamal" ) func BenchmarkElgGenerate(b *testing.B) { @@ -46,7 +47,6 @@ func BenchmarkElgDecrypt(b *testing.B) { } } log.Infof("%d fails %d rounds", fails, b.N) - } func BenchmarkElgEncrypt(b *testing.B) { diff --git a/lib/crypto/encrypt.go b/lib/crypto/encrypt.go index 835b215..e42451d 100644 --- a/lib/crypto/encrypt.go +++ b/lib/crypto/encrypt.go @@ -8,7 +8,6 @@ type Encrypter interface { } type PublicEncryptionKey interface { - // create a new encrypter to encrypt data to this public key NewEncrypter() (Encrypter, error) diff --git a/lib/crypto/hmac.go b/lib/crypto/hmac.go index 3774bbe..dd13e1e 100644 --- a/lib/crypto/hmac.go +++ b/lib/crypto/hmac.go @@ -4,11 +4,15 @@ import ( "crypto/md5" ) -const IPAD = byte(0x36) -const OPAD = byte(0x5C) +const ( + IPAD = byte(0x36) + OPAD = byte(0x5C) +) -type HMACKey [32]byte -type HMACDigest [16]byte +type ( + HMACKey [32]byte + HMACDigest [16]byte +) func (hk HMACKey) xor(p byte) (i []byte) { i = make([]byte, 64) @@ -25,7 +29,6 @@ func (hk HMACKey) xor(p byte) (i []byte) { // do i2p hmac func I2PHMAC(data []byte, k HMACKey) (d HMACDigest) { - buff := make([]byte, 64+len(data)) ip := k.xor(IPAD) copy(buff, ip) diff --git a/lib/crypto/rsa.go b/lib/crypto/rsa.go index 61c808d..7e46f7e 100644 --- a/lib/crypto/rsa.go +++ b/lib/crypto/rsa.go @@ -1,10 +1,16 @@ package crypto -type RSA2048PublicKey [256]byte -type RSA2048PrivateKey [512]byte +type ( + RSA2048PublicKey [256]byte + RSA2048PrivateKey [512]byte +) -type RSA3072PublicKey [384]byte -type RSA3072PrivateKey [786]byte +type ( + RSA3072PublicKey [384]byte + RSA3072PrivateKey [786]byte +) -type RSA4096PublicKey [512]byte -type RSA4096PrivateKey [1024]byte +type ( + RSA4096PublicKey [512]byte + RSA4096PrivateKey [1024]byte +) diff --git a/lib/crypto/sign.go b/lib/crypto/sign.go index b3b4ccb..0b88678 100644 --- a/lib/crypto/sign.go +++ b/lib/crypto/sign.go @@ -4,9 +4,11 @@ import ( "errors" ) -var ErrBadSignatureSize = errors.New("bad signature size") -var ErrInvalidKeyFormat = errors.New("invalid key format") -var ErrInvalidSignature = errors.New("invalid signature") +var ( + ErrBadSignatureSize = errors.New("bad signature size") + ErrInvalidKeyFormat = errors.New("invalid key format") + ErrInvalidSignature = errors.New("invalid signature") +) // type for verifying signatures type Verifier interface { diff --git a/lib/crypto/tunnel.go b/lib/crypto/tunnel.go index 4ce2539..e681fec 100644 --- a/lib/crypto/tunnel.go +++ b/lib/crypto/tunnel.go @@ -19,7 +19,6 @@ type Tunnel struct { } func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error) { - t = new(Tunnel) t.layerKey, err = aes.NewCipher(layerKey[:]) if err == nil { diff --git a/lib/i2np/build_request_record.go b/lib/i2np/build_request_record.go index 827f1ba..d986b06 100644 --- a/lib/i2np/build_request_record.go +++ b/lib/i2np/build_request_record.go @@ -149,8 +149,10 @@ padding :: Data total length: 222 */ -type BuildRequestRecordElGamalAES [528]byte -type BuildRequestRecordElGamal [528]byte +type ( + BuildRequestRecordElGamalAES [528]byte + BuildRequestRecordElGamal [528]byte +) type BuildRequestRecord struct { ReceiveTunnel tunnel.TunnelID diff --git a/lib/i2np/build_request_record_test.go b/lib/i2np/build_request_record_test.go index b381df1..451c0a4 100644 --- a/lib/i2np/build_request_record_test.go +++ b/lib/i2np/build_request_record_test.go @@ -14,7 +14,6 @@ func TestReadBuildRequestRecordReceiveTunnelTooLittleData(t *testing.T) { receive_tunnel, err := readBuildRequestRecordReceiveTunnel([]byte{0x01}) assert.Equal(tunnel.TunnelID(0), receive_tunnel) assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err) - } func TestReadBuildRequestRecordReceiveTunnelValidData(t *testing.T) { diff --git a/lib/i2np/build_response_record.go b/lib/i2np/build_response_record.go index 30f12c7..b405521 100644 --- a/lib/i2np/build_response_record.go +++ b/lib/i2np/build_response_record.go @@ -38,8 +38,10 @@ byte 527 :: reply total length: 528 */ -type BuildResponseRecordELGamalAES [528]byte -type BuildResponseRecordELGamal [528]byte +type ( + BuildResponseRecordELGamalAES [528]byte + BuildResponseRecordELGamal [528]byte +) type BuildResponseRecord struct { Hash common.Hash diff --git a/lib/netdb/reseed/reseed.go b/lib/netdb/reseed/reseed.go index e28fbc4..2d52402 100644 --- a/lib/netdb/reseed/reseed.go +++ b/lib/netdb/reseed/reseed.go @@ -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) } zip := filepath.Join(config.RouterConfigProperties.NetDb.Path, "reseed.zip") - err = os.WriteFile(zip, content, 0644) + err = os.WriteFile(zip, content, 0o644) if err != nil { 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) if err != nil { return nil, err diff --git a/lib/netdb/std.go b/lib/netdb/std.go index ed8d864..1465c03 100644 --- a/lib/netdb/std.go +++ b/lib/netdb/std.go @@ -154,7 +154,7 @@ func (db *StdNetDB) RecalculateSize() (err error) { if err == nil { str := fmt.Sprintf("%d", count) 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 { _, err = io.WriteString(f, str) f.Close() @@ -182,8 +182,8 @@ func (db *StdNetDB) Exists() bool { func (db *StdNetDB) SaveEntry(e *Entry) (err error) { var f io.WriteCloser h := e.RouterInfo.IdentHash() - //if err == nil { - f, err = os.OpenFile(db.SkiplistFile(h), os.O_WRONLY|os.O_CREATE, 0700) + // if err == nil { + f, err = os.OpenFile(db.SkiplistFile(h), os.O_WRONLY|os.O_CREATE, 0o700) if err == nil { err = e.WriteTo(f) f.Close() @@ -224,7 +224,7 @@ func (db *StdNetDB) Ensure() (err error) { // create base network database directory func (db *StdNetDB) Create() (err error) { - mode := os.FileMode(0700) + mode := os.FileMode(0o700) p := db.Path() log.Infof("Create network database in %s", p) diff --git a/lib/su3/su3.go b/lib/su3/su3.go index 2cae207..64d7718 100644 --- a/lib/su3/su3.go +++ b/lib/su3/su3.go @@ -146,29 +146,31 @@ var contentTypes = map[byte]ContentType{ 0x05: BLOCKLIST, } -var ErrMissingMagicBytes = errors.New("missing magic bytes") -var ErrMissingUnusedByte6 = errors.New("missing unused byte 6") -var ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version") -var ErrMissingSignatureType = errors.New("missing or invalid signature type") -var ErrUnsupportedSignatureType = errors.New("unsupported signature type") -var ErrMissingSignatureLength = errors.New("missing signature length") -var ErrMissingUnusedByte12 = errors.New("missing unused byte 12") -var ErrMissingVersionLength = errors.New("missing version length") -var ErrVersionTooShort = errors.New("version length too short") -var ErrMissingUnusedByte14 = errors.New("missing unused byte 14") -var ErrMissingSignerIDLength = errors.New("missing signer ID length") -var ErrMissingContentLength = errors.New("missing content length") -var ErrMissingUnusedByte24 = errors.New("missing unused byte 24") -var ErrMissingFileType = errors.New("missing or invalid file type") -var ErrMissingUnusedByte26 = errors.New("missing unused byte 26") -var ErrMissingContentType = errors.New("missing or invalid content type") -var ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39") -var ErrMissingVersion = errors.New("missing version") -var ErrMissingSignerID = errors.New("missing signer ID") -var ErrMissingContent = errors.New("missing content") -var ErrMissingSignature = errors.New("missing signature") -var ErrInvalidPublicKey = errors.New("invalid public key") -var ErrInvalidSignature = errors.New("invalid signature") +var ( + ErrMissingMagicBytes = errors.New("missing magic bytes") + ErrMissingUnusedByte6 = errors.New("missing unused byte 6") + ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version") + ErrMissingSignatureType = errors.New("missing or invalid signature type") + ErrUnsupportedSignatureType = errors.New("unsupported signature type") + ErrMissingSignatureLength = errors.New("missing signature length") + ErrMissingUnusedByte12 = errors.New("missing unused byte 12") + ErrMissingVersionLength = errors.New("missing version length") + ErrVersionTooShort = errors.New("version length too short") + ErrMissingUnusedByte14 = errors.New("missing unused byte 14") + ErrMissingSignerIDLength = errors.New("missing signer ID length") + ErrMissingContentLength = errors.New("missing content length") + ErrMissingUnusedByte24 = errors.New("missing unused byte 24") + ErrMissingFileType = errors.New("missing or invalid file type") + ErrMissingUnusedByte26 = errors.New("missing unused byte 26") + ErrMissingContentType = errors.New("missing or invalid content type") + ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39") + ErrMissingVersion = errors.New("missing version") + ErrMissingSignerID = errors.New("missing signer ID") + ErrMissingContent = errors.New("missing content") + ErrMissingSignature = errors.New("missing signature") + ErrInvalidPublicKey = errors.New("invalid public key") + ErrInvalidSignature = errors.New("invalid signature") +) const magicBytes = "I2Psu3" diff --git a/lib/su3/su3_test.go b/lib/su3/su3_test.go index b56e9bd..aca345c 100644 --- a/lib/su3/su3_test.go +++ b/lib/su3/su3_test.go @@ -9,11 +9,12 @@ import ( "encoding/binary" "encoding/pem" "fmt" - "github.com/stretchr/testify/assert" "io" "io/ioutil" "os" "testing" + + "github.com/stretchr/testify/assert" ) 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. -var aliceFakeKey *rsa.PrivateKey -var bobFakeKey *rsa.PrivateKey -var aliceContent []byte -var aliceSignature []byte -var aliceSU3 []byte +var ( + aliceFakeKey *rsa.PrivateKey + bobFakeKey *rsa.PrivateKey + aliceContent []byte + aliceSignature []byte + aliceSU3 []byte +) func TestRead(t *testing.T) { tests := []struct { diff --git a/lib/transport/messages/message.go b/lib/transport/messages/message.go index 8e87f53..f7fc337 100644 --- a/lib/transport/messages/message.go +++ b/lib/transport/messages/message.go @@ -46,10 +46,12 @@ package ntcp type MessageType uint8 -const MessageTypeSessionRequest = 0x00 -const MessageTypeSessionCreated = 0x01 -const MessageTypeSessionConfirmed = 0x02 -const MessageTypeData = 0x03 +const ( + MessageTypeSessionRequest = 0x00 + MessageTypeSessionCreated = 0x01 + MessageTypeSessionConfirmed = 0x02 + MessageTypeData = 0x03 +) type Message interface { // Type returns the message type diff --git a/lib/transport/noise/noise.go b/lib/transport/noise/noise.go index ad785f7..dff729b 100644 --- a/lib/transport/noise/noise.go +++ b/lib/transport/noise/noise.go @@ -10,7 +10,7 @@ import ( ) // wrapper around flynn/noise with just enough options exposed to enable configuring NTCP2 - +// possible and/or relatively intuitive type Noise struct { noise.Config router_address.RouterAddress // always the local addr @@ -42,10 +42,11 @@ func (ns *Noise) lockMutex() { } } -var ex_ns net.Conn = &NoiseConn{} -var ex_ns_l net.Listener = &NoiseListener{} -var ex_ns_u net.PacketConn = &NoisePacketConn{} -//var ex_tc_up net.PacketConn = &NoiseConn{} +var ( + ex_ns net.Conn = &NoiseConn{} + ex_ns_l net.Listener = &NoiseListener{} + ex_ns_u net.PacketConn = &NoisePacketConn{} +) func NewNoise(ra router_address.RouterAddress) (ns *Noise, err error) { ns = &Noise{} @@ -53,8 +54,10 @@ func NewNoise(ra router_address.RouterAddress) (ns *Noise, err error) { ns.Config = noise.Config{ CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256), Pattern: noise.HandshakeXK, - //StaticKeypair: , - //EphemeralKeypair: , + // 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. + // pretty sure that's no biggie but designing it has been... wierd? probably overthinking it. + // StaticKeypair: , + // EphemeralKeypair: , } return } @@ -67,35 +70,60 @@ func (ns *Noise) Addr() net.Addr { 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.Initiator = false network := "tcp" + var host net.Addr + var port string if ns.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) { @@ -111,7 +139,7 @@ func (ns *Noise) ListenNoise() (list NoiseListener, err error) { return } portNum, _ := strconv.Atoi(port) - port = strconv.Itoa(portNum+1) + port = strconv.Itoa(portNum + 1) hostip := net.JoinHostPort(host.String(), port) listener, err := net.Listen(network, hostip) if err != nil { diff --git a/lib/transport/noise/noise_conn.go b/lib/transport/noise/noise_conn.go index f519257..316c7d1 100644 --- a/lib/transport/noise/noise_conn.go +++ b/lib/transport/noise/noise_conn.go @@ -27,23 +27,29 @@ func (nc *NoiseConn) LocalAddr() net.Addr { // Write implements net.Conn. func (nc *NoiseConn) Write(b []byte) (n int, err error) { nc.lockMutex() - if nc.HandshakeState == nil { - nc.unlockMutex() - } else { + if nc.HandshakeState != nil { defer nc.unlockMutex() for nc.HandshakeState != nil && len(b) > 0 { 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() if err != nil { 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 { + // choose either the length of b or the maximum length of a message 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]) if err != nil { return n, err } + // write the message buffer to the socket _, err = nc.Conn.Write(nc.writeMsgBuf) if err != nil { return n, err @@ -54,6 +60,7 @@ func (nc *NoiseConn) Write(b []byte) (n int, err error) { } } nc.unlockMutex() + // zero-out the write buffer nc.writeMsgBuf = nc.writeMsgBuf[:0] for len(b) > 0 { outlen := len(nc.writeMsgBuf) @@ -76,7 +83,6 @@ func (nc *NoiseConn) Write(b []byte) (n int, err error) { nc.writeMsgBuf = nc.writeMsgBuf[:0] } } - if len(nc.writeMsgBuf) > 0 { _, err = nc.Conn.Write(nc.writeMsgBuf) if err != nil { diff --git a/lib/transport/noise/noise_conn_util.go b/lib/transport/noise/noise_conn_util.go index 2b7d482..b560cd7 100644 --- a/lib/transport/noise/noise_conn_util.go +++ b/lib/transport/noise/noise_conn_util.go @@ -2,6 +2,8 @@ package 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) { nc.readMsgBuf, err = nc.ReadMsg(nc.readMsgBuf[:0]) if err != nil { @@ -35,7 +37,7 @@ func (nc *NoiseConn) HandshakeStateCreate(out, payload []byte) (by []byte, err e //} nc.SetCipherStates(cs1, cs2) nc.HandshakeStateResponsibility = false - //nc.readBarrier.Release() + // nc.readBarrier.Release() 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 } if nc.send != nil { - //nc.readBarrier.Release() + // nc.readBarrier.Release() nc.handshakeHash = nc.HandshakeState.ChannelBinding() nc.HandshakeState = nil } diff --git a/lib/transport/noise/noise_packetconn.go b/lib/transport/noise/noise_packetconn.go index 73ab43c..7dc4b7b 100644 --- a/lib/transport/noise/noise_packetconn.go +++ b/lib/transport/noise/noise_packetconn.go @@ -7,13 +7,29 @@ import ( type NoisePacketConn struct { *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. -// 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 { - return n.PacketConn.Close() + return n.Conn.Close() } // LocalAddr implements net.PacketConn. diff --git a/lib/transport/ntcp/session.go b/lib/transport/ntcp/session.go index cb36582..05ef411 100644 --- a/lib/transport/ntcp/session.go +++ b/lib/transport/ntcp/session.go @@ -2,5 +2,4 @@ package ntcp // Session implements TransportSession // An established transport session -type Session struct { -} +type Session struct{} diff --git a/lib/transport/ntcp/transport.go b/lib/transport/ntcp/transport.go index 69a4f15..0b12900 100644 --- a/lib/transport/ntcp/transport.go +++ b/lib/transport/ntcp/transport.go @@ -11,5 +11,4 @@ const ( ) // Transport is an ntcp transport implementing transport.Transport interface -type Transport struct { -} +type Transport struct{} diff --git a/lib/tunnel/delivery.go b/lib/tunnel/delivery.go index c6837dc..336940f 100644 --- a/lib/tunnel/delivery.go +++ b/lib/tunnel/delivery.go @@ -708,6 +708,7 @@ func maybeAppendDelay(di_flag DeliveryInstructions, data, current []byte) (now [ } return } + func maybeAppendMessageID(di_flag DeliveryInstructions, di_type int, data, current []byte) (now []byte, err error) { if di_type == FIRST_FRAGMENT { if fragmented, _ := di_flag.Fragmented(); fragmented { diff --git a/lib/tunnel/message.go b/lib/tunnel/message.go index b4a0882..af72ed7 100644 --- a/lib/tunnel/message.go +++ b/lib/tunnel/message.go @@ -2,6 +2,7 @@ package tunnel import ( "encoding/binary" + "github.com/go-i2p/go-i2p/lib/crypto" log "github.com/sirupsen/logrus" ) diff --git a/lib/tunnel/message_test.go b/lib/tunnel/message_test.go index 3a28689..c817357 100644 --- a/lib/tunnel/message_test.go +++ b/lib/tunnel/message_test.go @@ -1,8 +1,9 @@ package tunnel import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestDeliveryInstructionDataWithNoPadding(t *testing.T) { @@ -33,7 +34,6 @@ func TestDeliveryInstructionDataWithSomePadding(t *testing.T) { copy(decrypted_tunnel_message[:], data) di := decrypted_tunnel_message.deliveryInstructionData() assert.Equal(1028-4-4-16-1-padding_size, len(di)) - } func TestDeliveryInstructionDataWithOnlyPadding(t *testing.T) { @@ -53,11 +53,9 @@ func TestDeliveryInstructionDataWithOnlyPadding(t *testing.T) { } func TestDeliveryInstructionsWithFragmentsWithAllPadding(t *testing.T) { - } // Test invalid delivery instructions and message fragments func TestDeliveryInstructionsWithFragmentsWithValidData(t *testing.T) { - } diff --git a/lib/tunnel/pool.go b/lib/tunnel/pool.go index de02722..611b2e1 100644 --- a/lib/tunnel/pool.go +++ b/lib/tunnel/pool.go @@ -1,5 +1,4 @@ package tunnel // a pool of tunnels which we have created -type Pool struct { -} +type Pool struct{} diff --git a/lib/util/signals/unix.go b/lib/util/signals/unix.go index 396e0ed..05a8d5c 100644 --- a/lib/util/signals/unix.go +++ b/lib/util/signals/unix.go @@ -27,5 +27,4 @@ func Handle() { // wtf? } } - } diff --git a/lib/util/signals/windows.go b/lib/util/signals/windows.go index eec09b5..e6ea973 100644 --- a/lib/util/signals/windows.go +++ b/lib/util/signals/windows.go @@ -25,5 +25,4 @@ func Handle() { // wtf? } } - } diff --git a/main.go b/main.go index 8ea1676..4d7ccde 100644 --- a/main.go +++ b/main.go @@ -1,12 +1,12 @@ package main import ( + "flag" + "github.com/go-i2p/go-i2p/lib/config" "github.com/go-i2p/go-i2p/lib/router" "github.com/go-i2p/go-i2p/lib/util/signals" log "github.com/sirupsen/logrus" - - "flag" ) func main() {