mirror of
https://github.com/asmogo/nws.git
synced 2024-12-12 18:36:22 +00:00
replaced nip04 with nip44 (#43)
* replaced nip04 with nip44 * Refactor key decoding logic to use common function * Refactor key decoding logic to use common function * fix nostr connection read test
This commit is contained in:
parent
646495de4c
commit
a77add0859
12
exit/exit.go
12
exit/exit.go
@ -4,6 +4,7 @@ import (
|
||||
"encoding/base32"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/ekzyis/nip44"
|
||||
"log/slog"
|
||||
"net"
|
||||
"strings"
|
||||
@ -15,7 +16,6 @@ import (
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/nip04"
|
||||
"github.com/nbd-wtf/go-nostr/nip19"
|
||||
"github.com/puzpuzpuz/xsync/v3"
|
||||
"golang.org/x/net/context"
|
||||
@ -227,12 +227,18 @@ func (e *Exit) ListenAndServe(ctx context.Context) {
|
||||
// processMessage decrypts and unmarshals the incoming event message, and then
|
||||
// routes the message to the appropriate handler based on its protocol type.
|
||||
func (e *Exit) processMessage(ctx context.Context, msg nostr.IncomingEvent) {
|
||||
sharedKey, err := nip04.ComputeSharedSecret(msg.PubKey, e.config.NostrPrivateKey)
|
||||
// hex decode the target public key
|
||||
privateKeyBytes, targetPublicKeyBytes, err := protocol.GetEncryptionKeys(e.config.NostrPrivateKey, msg.PubKey)
|
||||
if err != nil {
|
||||
slog.Error("could not get encryption keys", "error", err)
|
||||
return
|
||||
}
|
||||
sharedKey, err := nip44.GenerateConversationKey(privateKeyBytes, targetPublicKeyBytes)
|
||||
if err != nil {
|
||||
slog.Error("could not compute shared key", "error", err)
|
||||
return
|
||||
}
|
||||
decodedMessage, err := nip04.Decrypt(msg.Content, sharedKey)
|
||||
decodedMessage, err := nip44.Decrypt(sharedKey, msg.Content)
|
||||
if err != nil {
|
||||
slog.Error("could not decrypt message", "error", err)
|
||||
return
|
||||
|
@ -19,8 +19,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/asmogo/nws/protocol"
|
||||
"github.com/ekzyis/nip44"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/nip04"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -63,7 +63,11 @@ func (e *Exit) StartReverseProxy(ctx context.Context, httpTarget string, port in
|
||||
|
||||
}
|
||||
|
||||
func (e *Exit) handleCertificateEvent(incomingEvent *nostr.IncomingEvent, ctx context.Context, cert tls.Certificate) (tls.Certificate, error) {
|
||||
func (e *Exit) handleCertificateEvent(
|
||||
incomingEvent *nostr.IncomingEvent,
|
||||
ctx context.Context,
|
||||
cert tls.Certificate,
|
||||
) (tls.Certificate, error) {
|
||||
slog.Info("found certificate event", "certificate", incomingEvent.Content)
|
||||
// load private key from file
|
||||
privateKeyEvent := e.pool.QuerySingle(ctx, e.config.NostrRelays, nostr.Filter{
|
||||
@ -74,11 +78,15 @@ func (e *Exit) handleCertificateEvent(incomingEvent *nostr.IncomingEvent, ctx co
|
||||
if privateKeyEvent == nil {
|
||||
return tls.Certificate{}, errNoCertificateEvent
|
||||
}
|
||||
sharedKey, err := nip04.ComputeSharedSecret(privateKeyEvent.PubKey, e.config.NostrPrivateKey)
|
||||
privateKeyBytes, targetPublicKeyBytes, err := protocol.GetEncryptionKeys(e.config.NostrPrivateKey, privateKeyEvent.PubKey)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
sharedKey, err := nip44.GenerateConversationKey(privateKeyBytes, targetPublicKeyBytes)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, fmt.Errorf("failed to compute shared key: %w", err)
|
||||
}
|
||||
decodedMessage, err := nip04.Decrypt(privateKeyEvent.Content, sharedKey)
|
||||
decodedMessage, err := nip44.Decrypt(sharedKey, privateKeyEvent.Content)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, fmt.Errorf("failed to decrypt private key: %w", err)
|
||||
}
|
||||
|
6
go.mod
6
go.mod
@ -1,9 +1,11 @@
|
||||
module github.com/asmogo/nws
|
||||
|
||||
go 1.21
|
||||
go 1.21.0
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2
|
||||
github.com/caarlos0/env/v11 v11.0.0
|
||||
github.com/ekzyis/nip44 v0.0.0-20240425094820-6a3d864c8f08
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/nbd-wtf/go-nostr v0.30.2
|
||||
@ -15,7 +17,6 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
||||
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@ -34,6 +35,7 @@ require (
|
||||
github.com/tidwall/gjson v1.14.4 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
|
4
go.sum
4
go.sum
@ -38,6 +38,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/ekzyis/nip44 v0.0.0-20240425094820-6a3d864c8f08 h1:4/W0TU+JXOxZhWYQKqGEnEHigOym+ilZUiWwtD/KQNo=
|
||||
github.com/ekzyis/nip44 v0.0.0-20240425094820-6a3d864c8f08/go.mod h1:SWpq7RYr0raQqGwJaSaCCWzKIuPHB+SmALuhCZd1dWI=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
@ -114,6 +116,8 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -15,9 +15,9 @@ import (
|
||||
|
||||
"github.com/asmogo/nws/protocol"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/ekzyis/nip44"
|
||||
"github.com/google/uuid"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/nip04"
|
||||
"github.com/nbd-wtf/go-nostr/nip19"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
@ -128,11 +128,16 @@ func (nc *NostrConnection) handleNostrRead(buffer []byte) (int, error) {
|
||||
continue
|
||||
}
|
||||
nc.readIDs = append(nc.readIDs, event.ID)
|
||||
sharedKey, err := nip04.ComputeSharedSecret(event.PubKey, nc.privateKey)
|
||||
// hex decode the target public key
|
||||
privateKeyBytes, targetPublicKeyBytes, err := protocol.GetEncryptionKeys(nc.privateKey, event.PubKey)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not get encryption keys: %w", err)
|
||||
}
|
||||
sharedKey, err := nip44.GenerateConversationKey(privateKeyBytes, targetPublicKeyBytes)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not compute shared key: %w", err)
|
||||
}
|
||||
decodedMessage, err := nip04.Decrypt(event.Content, sharedKey)
|
||||
decodedMessage, err := nip44.Decrypt(sharedKey, event.Content)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not decrypt message: %w", err)
|
||||
}
|
||||
@ -387,7 +392,7 @@ func WithTargetPublicKey(pubKey string) NostrConnOption {
|
||||
func WithSub(...bool) NostrConnOption {
|
||||
return func(connection *NostrConnection) {
|
||||
connection.sub = true
|
||||
go connection.handleSubscription()
|
||||
//go connection.handleSubscription()
|
||||
}
|
||||
}
|
||||
|
||||
@ -406,30 +411,3 @@ func WithUUID(uuid uuid.UUID) NostrConnOption {
|
||||
connection.uuid = uuid
|
||||
}
|
||||
}
|
||||
|
||||
// handleSubscription handles the subscription channel for incoming events.
|
||||
// It continuously listens for events on the subscription channel and performs necessary operations.
|
||||
// If the event has a valid relay, it computes the shared key and decrypts the event content.
|
||||
// The decrypted message is then written to the read buffer.
|
||||
// If the context is canceled, the method returns.
|
||||
func (nc *NostrConnection) handleSubscription() {
|
||||
for {
|
||||
select {
|
||||
case event := <-nc.subscriptionChan:
|
||||
if event.Relay == nil {
|
||||
continue
|
||||
}
|
||||
sharedKey, err := nip04.ComputeSharedSecret(event.PubKey, nc.privateKey)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
decodedMessage, err := nip04.Decrypt(event.Content, sharedKey)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
nc.readBuffer.Write([]byte(decodedMessage))
|
||||
case <-nc.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package netstr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/asmogo/nws/protocol"
|
||||
"github.com/ekzyis/nip44"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"runtime"
|
||||
"testing"
|
||||
@ -41,7 +44,7 @@ func TestNostrConnection_Read(t *testing.T) {
|
||||
Event: &nostr.Event{
|
||||
ID: "eventID",
|
||||
PubKey: "8f97a664471f0b6d599a1e4a781c9a25f39902d96fb462c08df48697bb851611",
|
||||
Content: "BnHzzyrUhKjDcDPOGfXJDYijUsgxw0hUZq2m+bX5QFI=?iv=NrEqv/jL+SASB2YTjo9i9Q=="}},
|
||||
Content: `AuaBj8mXZ9n9IfdonNra0lpaed6Alc+H0xjUdyN9h6mCSuy7ZrEjWUZQj4HWNd4P1RCme1pda0z8hyItT4nVzESByRiQT5+hf+ij0aJw9+DW/ggJIWGbpm4wp7bk4loYKdERr+nzorqEjWNzpxsJXhXJ0nKtIxu61To5XY4SjuMqpUuOtznuHiPJJhKNWSSRPV92L/iVoOnjKJhfR5jOWBK3vA==`}},
|
||||
nc: func() *NostrConnection {
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
return &NostrConnection{
|
||||
@ -52,7 +55,7 @@ func TestNostrConnection_Read(t *testing.T) {
|
||||
privateKey: "788de536151854213cc28dff9c3042e7897f0a1d59b391ddbbc1619d7e716e78",
|
||||
}
|
||||
},
|
||||
wantN: 11, // hello world
|
||||
wantN: 5, // hello world
|
||||
wantErr: false,
|
||||
},
|
||||
// Add more cases here to cover more corner situations
|
||||
@ -62,6 +65,17 @@ func TestNostrConnection_Read(t *testing.T) {
|
||||
nc := tt.nc()
|
||||
defer nc.Close()
|
||||
b := make([]byte, 1024)
|
||||
if tt.event.Event != nil {
|
||||
private, public, err := protocol.GetEncryptionKeys(nc.privateKey, tt.event.PubKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sharedKey, err := nip44.GenerateConversationKey(private, public)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(nip44.Encrypt(sharedKey, tt.event.Content, &nip44.EncryptOptions{}))
|
||||
}
|
||||
nc.subscriptionChan <- tt.event
|
||||
gotN, err := nc.Read(b)
|
||||
if (err != nil) != tt.wantErr {
|
||||
|
17
protocol/nip44.go
Normal file
17
protocol/nip44.go
Normal file
@ -0,0 +1,17 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func GetEncryptionKeys(privateKey, publicKey string) ([]byte, []byte, error) {
|
||||
targetPublicKeyBytes, err := hex.DecodeString("02" + publicKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
privateKeyBytes, err := hex.DecodeString(privateKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return privateKeyBytes, targetPublicKeyBytes, nil
|
||||
}
|
@ -2,8 +2,9 @@ package protocol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ekzyis/nip44"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/nip04"
|
||||
)
|
||||
|
||||
// KindEphemeralEvent represents the unique identifier for ephemeral events.
|
||||
@ -64,7 +65,11 @@ func (s *EventSigner) CreateSignedEvent(
|
||||
tags nostr.Tags,
|
||||
opts ...MessageOption,
|
||||
) (nostr.Event, error) {
|
||||
sharedKey, err := nip04.ComputeSharedSecret(targetPublicKey, s.privateKey)
|
||||
privateKeyBytes, targetPublicKeyBytes, err := GetEncryptionKeys(s.privateKey, targetPublicKey)
|
||||
if err != nil {
|
||||
return nostr.Event{}, fmt.Errorf("could not get encryption keys: %w", err)
|
||||
}
|
||||
sharedKey, err := nip44.GenerateConversationKey(privateKeyBytes, targetPublicKeyBytes)
|
||||
if err != nil {
|
||||
return nostr.Event{}, fmt.Errorf("could not compute shared key: %w", err)
|
||||
}
|
||||
@ -75,7 +80,10 @@ func (s *EventSigner) CreateSignedEvent(
|
||||
if err != nil {
|
||||
return nostr.Event{}, fmt.Errorf("could not marshal message: %w", err)
|
||||
}
|
||||
encryptedMessage, err := nip04.Encrypt(string(messageJSON), sharedKey)
|
||||
encryptedMessage, err := nip44.Encrypt(sharedKey, string(messageJSON), &nip44.EncryptOptions{
|
||||
Salt: nil,
|
||||
Version: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return nostr.Event{}, fmt.Errorf("could not encrypt message: %w", err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user