From 54ab0fefdc31425a1b364d218fba6f8e1ed745df Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Fri, 28 Oct 2022 14:22:46 +0000 Subject: [PATCH 1/2] Increse otp digits generated by defaults The OTP library supports just the minimum of up to 9 digits which is what is documented in https://www.rfc-editor.org/rfc/rfc4226#section-5.3. While this is perfectly fine for human usage, also RFC defines that this is an example and more digits should be used for a in increased security. As our case is not human-facing, we can bump this to the maximum size allowed by the hashing algorithm. Credits to @aleksej-paschenko for discoverying that the gotp lib returned 0 padded strings! --- go.mod | 4 +++- go.sum | 4 ++-- pkg/crypto/otp.go | 31 +++++++++++++++++++++++++++++++ pkg/discovery/dht.go | 7 +++---- pkg/hub/hub.go | 8 ++++---- pkg/node/connection.go | 4 ++-- pkg/node/node.go | 2 +- pkg/node/options.go | 21 +++++++++++++-------- 8 files changed, 59 insertions(+), 22 deletions(-) create mode 100644 pkg/crypto/otp.go diff --git a/go.mod b/go.mod index 5e0c556a..c13b4362 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/c-robinson/iplib v1.0.3 github.com/cenkalti/backoff/v4 v4.1.3 github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/creachadair/otp v0.3.2 github.com/google/btree v1.1.2 // indirect github.com/google/gopacket v1.1.19 github.com/hashicorp/errwrap v1.1.0 // indirect @@ -37,7 +38,6 @@ require ( github.com/urfave/cli v1.22.10 github.com/vishvananda/netlink v1.1.0 github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect - github.com/xlzd/gotp v0.0.0-20220817083547-a63b9d03d72f go.uber.org/zap v1.23.0 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect @@ -46,3 +46,5 @@ require ( ) replace github.com/elastic/gosigar => github.com/mudler/gosigar v0.14.3-0.20220502202347-34be910bdaaf + +replace github.com/creachadair/otp => github.com/mudler/otp v0.0.0-20221028140802-168056309dfc diff --git a/go.sum b/go.sum index b721bce9..05b40210 100644 --- a/go.sum +++ b/go.sum @@ -543,6 +543,8 @@ github.com/mudler/go-processmanager v0.0.0-20220724164624-c45b5c61312d h1:/lAg9v github.com/mudler/go-processmanager v0.0.0-20220724164624-c45b5c61312d/go.mod h1:HGGAOJhipApckwNV8ZTliRJqxctUv3xRY+zbQEwuytc= github.com/mudler/gosigar v0.14.3-0.20220502202347-34be910bdaaf h1:hNa6C3a7+14a2qwMkYZbq94ddebYc8CloF2KOVytf+A= github.com/mudler/gosigar v0.14.3-0.20220502202347-34be910bdaaf/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/mudler/otp v0.0.0-20221028140802-168056309dfc h1:J7yENI2ZTlOOg+8Bkxd1jkgXJkwSgDWh1PkBBfYJkOI= +github.com/mudler/otp v0.0.0-20221028140802-168056309dfc/go.mod h1:mDkCUSoWN8zqxFoDMw20Boe6xeDd1jJuy6pNQQ4lCy4= github.com/mudler/water v0.0.0-20221010214108-8c7313014ce0 h1:Qh6ghkMgTu6siFbTf7L3IszJmshMhXxNL4V+t7IIA6w= github.com/mudler/water v0.0.0-20221010214108-8c7313014ce0/go.mod h1:nViSE8jcOcraZwhi34joEqn7HYFISgs0M8/YujzY5Xk= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= @@ -773,8 +775,6 @@ github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1 github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xlzd/gotp v0.0.0-20220817083547-a63b9d03d72f h1:C8De+7emQKojPBC+mXA0fr39XN5mKjRm9IUzdxI4whI= -github.com/xlzd/gotp v0.0.0-20220817083547-a63b9d03d72f/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/pkg/crypto/otp.go b/pkg/crypto/otp.go new file mode 100644 index 00000000..dc2c0bf7 --- /dev/null +++ b/pkg/crypto/otp.go @@ -0,0 +1,31 @@ +/* +Copyright © 2022 Ettore Di Giacinto +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package crypto + +import ( + "hash" + + "github.com/creachadair/otp" +) + +func TOTP(f func() hash.Hash, digits int, t int, key string) string { + cfg := otp.Config{ + Hash: f, // default is sha1.New + Digits: digits, // default is 6 + TimeStep: otp.TimeWindow(t), + Key: key, + NoTrunc: true, + } + return cfg.TOTP() +} diff --git a/pkg/discovery/dht.go b/pkg/discovery/dht.go index 5a2a4fb4..b928d3e0 100644 --- a/pkg/discovery/dht.go +++ b/pkg/discovery/dht.go @@ -15,6 +15,7 @@ package discovery import ( "context" + "crypto/sha256" "sync" "time" @@ -29,7 +30,6 @@ import ( "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/routing" discovery "github.com/libp2p/go-libp2p/p2p/discovery/routing" - "github.com/xlzd/gotp" ) type DHT struct { @@ -56,10 +56,9 @@ func (d *DHT) Option(ctx context.Context) func(c *libp2p.Config) error { } func (d *DHT) Rendezvous() string { if d.OTPKey != "" { - totp := gotp.NewTOTP(d.OTPKey, d.KeyLength, d.OTPInterval, nil) + totp := internalCrypto.TOTP(sha256.New, d.KeyLength, d.OTPInterval, d.OTPKey) - //totp := gotp.NewDefaultTOTP(d.OTPKey) - rv := internalCrypto.MD5(totp.Now()) + rv := internalCrypto.MD5(totp) d.latestRendezvous = rv return rv } diff --git a/pkg/hub/hub.go b/pkg/hub/hub.go index 8439d9e6..93b1101e 100644 --- a/pkg/hub/hub.go +++ b/pkg/hub/hub.go @@ -17,13 +17,13 @@ package hub import ( "context" + "crypto/sha256" "errors" "strings" "sync" "time" "github.com/mudler/edgevpn/pkg/crypto" - "github.com/xlzd/gotp" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/host" @@ -54,11 +54,11 @@ func NewHub(otp string, maxsize, keyLength, interval int, joinPublic bool) *Mess } func (m *MessageHub) topicKey(salts ...string) string { - totp := gotp.NewTOTP(strings.ToUpper(m.otpKey), m.keyLength, m.interval, nil) + totp := crypto.TOTP(sha256.New, m.keyLength, m.interval, m.otpKey) if len(salts) > 0 { - return crypto.MD5(totp.Now() + strings.Join(salts, ":")) + return crypto.MD5(totp + strings.Join(salts, ":")) } - return crypto.MD5(totp.Now()) + return crypto.MD5(totp) } func (m *MessageHub) joinRoom(host host.Host) error { diff --git a/pkg/node/connection.go b/pkg/node/connection.go index 08f82fde..9112d690 100644 --- a/pkg/node/connection.go +++ b/pkg/node/connection.go @@ -16,6 +16,7 @@ package node import ( "context" "crypto/rand" + "crypto/sha256" "io" mrand "math/rand" "net" @@ -29,7 +30,6 @@ import ( conngater "github.com/libp2p/go-libp2p/p2p/net/conngater" hub "github.com/mudler/edgevpn/pkg/hub" multiaddr "github.com/multiformats/go-multiaddr" - "github.com/xlzd/gotp" ) // Host returns the libp2p peer host @@ -115,7 +115,7 @@ func (e *Node) genHost(ctx context.Context) (host.Host, error) { } func (e *Node) sealkey() string { - return internalCrypto.MD5(gotp.NewTOTP(e.config.ExchangeKey, e.config.SealKeyLength, e.config.SealKeyInterval, nil).Now()) + return internalCrypto.MD5(internalCrypto.TOTP(sha256.New, e.config.SealKeyLength, e.config.SealKeyInterval, e.config.ExchangeKey)) } func (e *Node) handleEvents(ctx context.Context, inputChannel chan *hub.Message, roomMessages chan *hub.Message, pub func(*hub.Message) error, handlers []Handler, peerGater bool) { diff --git a/pkg/node/node.go b/pkg/node/node.go index 68b27a90..bfe2fc43 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -61,7 +61,7 @@ func New(p ...Option) (*Node, error) { StreamHandlers: make(map[protocol.Protocol]StreamHandler), LedgerAnnounceTime: 5 * time.Second, LedgerSyncronizationTime: 5 * time.Second, - SealKeyLength: 12, + SealKeyLength: defaultKeyLength, Options: defaultLibp2pOptions, Logger: logger.New(log.LevelDebug), Sealer: &crypto.AESSealer{}, diff --git a/pkg/node/options.go b/pkg/node/options.go index 39e7cce1..6a884cea 100644 --- a/pkg/node/options.go +++ b/pkg/node/options.go @@ -25,7 +25,6 @@ import ( "github.com/mudler/edgevpn/pkg/protocol" "github.com/mudler/edgevpn/pkg/utils" "github.com/pkg/errors" - "github.com/xlzd/gotp" "gopkg.in/yaml.v2" ) @@ -286,12 +285,18 @@ func (y YAMLConnectionConfig) copy(mdns, dht bool, cfg *Config, d *discovery.DHT cfg.MaxMessageSize = y.MaxMessageSize } -const defaultKeyLength = 32 +const defaultKeyLength = 43 func GenerateNewConnectionData(i ...int) *YAMLConnectionConfig { defaultInterval := 9000 maxMessSize := 20 << 20 // 20MB - if len(i) >= 2 { + keyLength := defaultKeyLength + + if len(i) >= 3 { + keyLength = i[2] + defaultInterval = i[0] + maxMessSize = i[1] + } else if len(i) >= 2 { defaultInterval = i[0] maxMessSize = i[1] } else if len(i) == 1 { @@ -300,17 +305,17 @@ func GenerateNewConnectionData(i ...int) *YAMLConnectionConfig { return &YAMLConnectionConfig{ MaxMessageSize: maxMessSize, - RoomName: gotp.RandomSecret(defaultKeyLength), - Rendezvous: utils.RandStringRunes(defaultKeyLength), - MDNS: utils.RandStringRunes(defaultKeyLength), + RoomName: utils.RandStringRunes(keyLength), + Rendezvous: utils.RandStringRunes(keyLength), + MDNS: utils.RandStringRunes(keyLength), OTP: OTP{ DHT: OTPConfig{ - Key: gotp.RandomSecret(defaultKeyLength), + Key: utils.RandStringRunes(keyLength), Interval: defaultInterval, Length: defaultKeyLength, }, Crypto: OTPConfig{ - Key: gotp.RandomSecret(defaultKeyLength), + Key: utils.RandStringRunes(keyLength), Interval: defaultInterval, Length: defaultKeyLength, }, From dfc5bf18724da6361a1aabec314b561e06a3e792 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Fri, 28 Oct 2022 14:40:32 +0000 Subject: [PATCH 2/2] Support alphanumeric in RandString --- pkg/utils/strings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/utils/strings.go b/pkg/utils/strings.go index 36ead7a8..a9b942ed 100644 --- a/pkg/utils/strings.go +++ b/pkg/utils/strings.go @@ -15,7 +15,7 @@ package utils import "math/rand" -var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") +var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") func RandStringRunes(n int) string { b := make([]rune, n)