Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/internal/sam/datagram.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"strconv"
"strings"
"time"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/interfaces/destination"
Expand Down Expand Up @@ -175,7 +176,7 @@ func (s *samSession) parseReceivedDatagram(delivery networking.StreamingTunnelDe
}
return foundation.EncodeI2PBase64(packet.V1.From.Bytes()), packet.V1.Payload, true
case networking.DatagramProtocolDatagram2:
valid, err := packet.V2.VerifyTarget(s.endpoint.Hash())
valid, err := packet.V2.VerifyTargetAt(s.endpoint.Hash(), uint32(time.Now().Unix()))
if err != nil || !valid || packet.V2.From.Hash() != delivery.From {
return "", nil, false
}
Expand Down
6 changes: 3 additions & 3 deletions client/internal/sam/private_destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ func parseOfflinePrivateKey(identity foundation.Identity, section []byte) (*offl
return nil, ErrInvalidKey
}
offset := 6
public := append([]byte(nil), section[offset:offset+publicLength]...)
public := section[offset : offset+publicLength]
offset += publicLength
signature := append([]byte(nil), section[offset:offset+signatureLength]...)
signature := section[offset : offset+signatureLength]
offset += signatureLength
transientPrivate := append([]byte(nil), section[offset:]...)
transientPrivate := section[offset:]
return &offlinePrivateKey{
OfflineSignature: foundation.OfflineSignature{
Expires: binary.BigEndian.Uint32(section[:4]),
Expand Down
8 changes: 8 additions & 0 deletions client/internal/sam/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ func (s *Server) createSession(ctx context.Context, connection *serverConnection
if meta, ok := local.OfflineSignature(); ok {
meta := meta
offline = &meta
if style == styleDatagram {
local.ReleaseSensitive()
return connection.writeLine("SESSION STATUS RESULT=INVALID_KEY")
}
if policy.Encrypted {
local.ReleaseSensitive()
return connection.writeLine("SESSION STATUS RESULT=INVALID_KEY")
}
}
private, err := encodePrivateDestination(local)
if err != nil {
Expand Down
5 changes: 4 additions & 1 deletion foundation/address_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,13 @@ func (d *LocalDestination) Sign(message []byte) ([]byte, error) {
if d.offline != nil {
switch d.offline.keyType {
case SigningEdDSASHA512Ed25519:
return ed25519.Sign(ed25519.NewKeyFromSeed(d.offline.private), message), nil
private := ed25519.NewKeyFromSeed(d.offline.private)
defer clear(private)
return ed25519.Sign(private, message), nil
case SigningRedDSASHA512Ed25519:
var private [32]byte
copy(private[:], d.offline.private)
defer clear(private[:])
return Red25519Sign(private, message)
default:
return nil, ErrEncryptedSigningKey
Expand Down
23 changes: 17 additions & 6 deletions foundation/offline_signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,24 @@ type OfflineSignature struct {
Signature []byte
}

// SignedContent returns the authorized content (expires, key type, public key)
// covered by the offline signature.
// SignedContentLen returns the encoded length of the authorized content.
func (o OfflineSignature) SignedContentLen() int { return 6 + len(o.PublicKey) }

// MarshalSignedContentTo serializes the authorized content into dst.
func (o OfflineSignature) MarshalSignedContentTo(dst []byte) (int, error) {
if len(dst) < o.SignedContentLen() {
return 0, ErrInvalidIdentity
}
binary.BigEndian.PutUint32(dst[:4], o.Expires)
binary.BigEndian.PutUint16(dst[4:6], uint16(o.Type))
copy(dst[6:], o.PublicKey)
return o.SignedContentLen(), nil
}

// SignedContent returns the authorized content (expires, key type, public key).
func (o OfflineSignature) SignedContent() []byte {
signed := make([]byte, 6+len(o.PublicKey))
binary.BigEndian.PutUint32(signed[:4], o.Expires)
binary.BigEndian.PutUint16(signed[4:6], uint16(o.Type))
copy(signed[6:], o.PublicKey)
signed := make([]byte, o.SignedContentLen())
_, _ = o.MarshalSignedContentTo(signed)
return signed
}

Expand Down