diff --git a/lib/crypto/aes.go b/lib/crypto/aes.go index d3f7def..5871506 100644 --- a/lib/crypto/aes.go +++ b/lib/crypto/aes.go @@ -1,28 +1 @@ package crypto - -type AesCBC struct { -} - -type AesECB struct { -} - - -type TunnelKey [32]byte -type TunnelIV [16]byte - -// -// tunnel aes base -// -type TunnelAes struct { - layerKey TunnelKey - ivKey TunnelKey - iv TunnelIV -} - -type TunnelEncryption struct { - TunnelAes -} - -type TunnelDecryption struct { - TunnelAes -} diff --git a/lib/crypto/tunnel.go b/lib/crypto/tunnel.go new file mode 100644 index 0000000..8ad09f6 --- /dev/null +++ b/lib/crypto/tunnel.go @@ -0,0 +1,49 @@ +package crypto +import ( + "crypto/aes" + "crypto/cipher" +) + +type TunnelData [1024]byte + +// A symetric key for encrypting tunnel messages +type TunnelKey [32]byte +// The initialization vector for a tunnel message +type TunnelIV []byte + +type Tunnel struct { + layerKey cipher.Block + ivKey cipher.Block +} + +func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error) { + + t = new(Tunnel) + t.layerKey, err = aes.NewCipher(layerKey[:]) + if err == nil { + t.ivKey, err = aes.NewCipher(ivKey[:]) + } + + if err != nil { + // error happened we don't need t + t = nil + } + return +} + +// encrypt tunnel data in place +func (t *Tunnel) Encrypt(td *TunnelData) { + data := *td + t.ivKey.Encrypt(data[16:1024], data[16:1024]) + layerBlock := cipher.NewCBCEncrypter(t.layerKey, data[:16]) + layerBlock.CryptBlocks(data[16:1024], data[16:1024]) + t.ivKey.Encrypt(data[16:1024], data[16:1024]) +} + +func (t *Tunnel) Decrypt(td *TunnelData) { + data := *td + t.ivKey.Decrypt(data[16:1024], data[16:1024]) + layerBlock := cipher.NewCBCDecrypter(t.layerKey, data[:16]) + layerBlock.CryptBlocks(data[16:1024], data[16:1024]) + t.ivKey.Decrypt(data[16:1024], data[16:1024]) +} diff --git a/lib/stdi2p/i2np.go b/lib/i2np/i2np.go similarity index 100% rename from lib/stdi2p/i2np.go rename to lib/i2np/i2np.go diff --git a/lib/tunnel/delivery.go b/lib/tunnel/delivery.go new file mode 100644 index 0000000..4eb478a --- /dev/null +++ b/lib/tunnel/delivery.go @@ -0,0 +1,68 @@ +package tunnel + +import( + "encoding/binary" +) + +const ( + DT_LOCAL = iota + DT_TUNNEL + DT_ROUTER + DT_UNUSED +) + +type DelayFactor byte + +type DeliveryInstructions []byte + + +func (di DeliveryInstructions) DeliveryType() byte { + return (di[0] & 0x30) >> 4 +} + + +func (di DeliveryInstructions) IsFragmented() bool { + return (di[0] & 0x08) == 0x08 +} + +// get the tunnel id in this devilevery instrcutions or 0 if not applicable +func (di DeliveryInstructions) TunnelID() (tid uint32) { + if di.DeliveryType() == DT_TUNNEL { + // TODO(psi): what if this is 0? + tid = binary.BigEndian.Uint32(di[1:5]) + } + return +} + +// do we have a delay factor? +func (di DeliveryInstructions) HasDelay() bool { + return (di[0] & 0x10) == 0x10 +} + +// get the delay factor if it exists +func (di DeliveryInstructions) Delay() (d DelayFactor) { + if di.HasDelay() { + t := di.DeliveryType() + if t == DT_TUNNEL { + d = DelayFactor(di[37]) + } else if t == DT_ROUTER { + d = DelayFactor(di[36]) + } + } + return +} + +func (di DeliveryInstructions) HasExtendedOptions() bool { + return (di[0] & 0x04) == 0x04 +} + +// get the to hash for these delivery instructions or nil if not applicable +func (di DeliveryInstructions) ToHash() (h []byte) { + t := di.DeliveryType() + if t == DT_TUNNEL { + h = di[5:37] + } else if t == DT_ROUTER || t == DT_LOCAL { + h = di[4:36] + } + return +} diff --git a/lib/tunnel/doc.go b/lib/tunnel/doc.go new file mode 100644 index 0000000..a207b64 --- /dev/null +++ b/lib/tunnel/doc.go @@ -0,0 +1,4 @@ +/* + i2p garlic tunnel implementation +*/ +package tunnel diff --git a/lib/tunnel/endpoint.go b/lib/tunnel/endpoint.go new file mode 100644 index 0000000..5bafef1 --- /dev/null +++ b/lib/tunnel/endpoint.go @@ -0,0 +1 @@ +package tunnel diff --git a/lib/tunnel/gateway.go b/lib/tunnel/gateway.go new file mode 100644 index 0000000..5bafef1 --- /dev/null +++ b/lib/tunnel/gateway.go @@ -0,0 +1 @@ +package tunnel diff --git a/lib/tunnel/message.go b/lib/tunnel/message.go new file mode 100644 index 0000000..22286ce --- /dev/null +++ b/lib/tunnel/message.go @@ -0,0 +1,20 @@ +package tunnel + +import ( + "github.com/bounce-chat/go-i2p/lib/crypto" + "encoding/binary" +) + +type TunnelID uint32 + +// data sent down a tunnel +type TunnelMessage crypto.TunnelData + +func (tm TunnelMessage) ID() (tid TunnelID) { + tid = TunnelID(binary.BigEndian.Uint32(tm[:4])) + return +} + +func (tm TunnelMessage) IV() crypto.TunnelIV { + return tm[4:20] +} diff --git a/lib/tunnel/participant.go b/lib/tunnel/participant.go new file mode 100644 index 0000000..0565407 --- /dev/null +++ b/lib/tunnel/participant.go @@ -0,0 +1,10 @@ +package tunnel + +import ( + "github.com/bounce-chat/go-i2p/lib/crypto" +) + +type Participant struct { + decryption *crypto.Tunnel +} +