add lease, lease_set, mapping, router_address, router_identity, and router_info

This commit is contained in:
Hayden Parker
2016-02-01 01:56:10 -08:00
parent cd14a81abb
commit 473e9e26ae
9 changed files with 387 additions and 0 deletions

View File

@ -94,3 +94,17 @@ func (c KeyCert) SigningPublicKey() (k crypto.SigningPublicKey) {
// TODO: rsa/eddsa
return
}
func (c Certificate) signatureSize() int {
sizes := map[int]int{
KEYCERT_SIGN_DSA_SHA1: 40,
KEYCERT_SIGN_P256: 64,
KEYCERT_SIGN_P384: 96,
KEYCERT_SIGN_P521: 132,
KEYCERT_SIGN_RSA2048: 256,
KEYCERT_SIGN_RSA3072: 384,
KEYCERT_SIGN_RSA4096: 512,
KEYCERT_SIGN_ED25519: 64,
}
return sizes[int(c.Type())]
}

View File

@ -0,0 +1,7 @@
package common
//
// Both Destination and RouterIdentity share the same structure
// https://geti2p.net/en/docs/spec/common-structures#struct_KeysAndCert
// Perhaps we can avoid repeating ourselves being using commong functions
//

28
lib/common/lease.go Normal file
View File

@ -0,0 +1,28 @@
package common
import (
"encoding/binary"
"github.com/bounce-chat/go-i2p/lib/tunnel"
)
const (
LEASE_SIZE = 44
)
type Lease [LEASE_SIZE]byte
func (lease Lease) TunnelGateway() (h IdentHash) {
copy(lease[:32], h[:])
return
}
func (lease Lease) TunnelID() tunnel.TunnelID {
return tunnel.TunnelID(
binary.BigEndian.Uint32(lease[32:36]),
)
}
func (lease Lease) Date() (d Date) {
copy(lease[36:], d[:])
return
}

85
lib/common/lease_set.go Normal file
View File

@ -0,0 +1,85 @@
package common
import (
"bytes"
"encoding/binary"
"github.com/bounce-chat/go-i2p/lib/crypto"
)
type LeaseSet []byte
func (lease_set LeaseSet) Destination() Destination {
return Destination(lease_set[:387])
}
func (lease_set LeaseSet) EncryptionKey() (k crypto.ElgPublicKey) {
copy(lease_set[387:387+256], k[:])
return
}
func (lease_set LeaseSet) SigningKey() (k []byte) {
size := lease_set.signingKeySize()
head := 387 + 256
copy(lease_set[head:head+size], k)
return
}
func (lease_set LeaseSet) LeaseCount() int {
head := 387 + 256 + lease_set.signingKeySize()
var count int
buf := bytes.NewReader(
[]byte{lease_set[head+1]},
)
binary.Read(buf, binary.BigEndian, &count)
return count
}
func (lease_set LeaseSet) Leases() []Lease {
leases := make([]Lease, 0)
offset := 387 + 256 + lease_set.signingKeySize() + 1
for i := 0; i < lease_set.LeaseCount(); i++ {
start := offset + (i * LEASE_SIZE)
end := offset + (start + LEASE_SIZE)
var lease Lease
copy(lease_set[start:end], lease[:])
leases = append(leases, lease)
}
return leases
}
func (lease_set LeaseSet) Signature() []byte {
data_end := 387 +
256 +
lease_set.signingKeySize() +
1 +
(LEASE_SIZE * lease_set.LeaseCount())
sig_size := lease_set.
Destination().
Certificate().
signatureSize()
return lease_set[data_end : data_end+sig_size]
}
func (lease_set LeaseSet) Verify() error {
data_end := 387 +
256 +
lease_set.signingKeySize() +
1 +
(LEASE_SIZE * lease_set.LeaseCount())
data := lease_set[:data_end]
verifier, err := lease_set.
Destination().
SigningPublicKey().
NewVerifier()
if err != nil {
return err
}
return verifier.Verify(data, lease_set.Signature())
}
func (lease_set LeaseSet) signingKeySize() int {
return lease_set.
Destination().
SigningPublicKey().
Len()
}

41
lib/common/mapping.go Normal file
View File

@ -0,0 +1,41 @@
package common
import (
"encoding/binary"
"strings"
)
type Mapping []byte
func (mapping Mapping) ToMap() map[string]string {
gomap := make(map[string]string)
kv_store := string(mapping[2:])
pairs := strings.Split(kv_store, ";")
for _, pair := range pairs {
values := strings.Split(pair, "=")
if len(values) != 2 {
continue
}
gomap[values[0]] = values[1]
}
return gomap
}
func MappingFromMap(gomap map[string]string) Mapping {
kv_store := make([]byte, 0)
for k, v := range gomap {
key_bytes := []byte(k)
key_bytes = append(key_bytes, 0x3d)
value_bytes := []byte(v)
value_bytes = append(value_bytes, 0x3b)
kv_store = append(kv_store, key_bytes...)
kv_store = append(kv_store, value_bytes...)
}
kv_size := uint16(len(kv_store))
var size [2]byte
binary.BigEndian.PutUint16(size[:], kv_size)
mapping := Mapping{}
mapping = append(mapping, size[:]...)
mapping = append(mapping, kv_store...)
return mapping
}

View File

@ -0,0 +1,37 @@
package common
import (
"bytes"
"testing"
)
func TestToMapping(t *testing.T) {
gomap := map[string]string{
"a": "1",
}
mapping := MappingFromMap(gomap)
if !bytes.Equal(mapping, []byte{0x00, 0x04, 0x61, 0x3d, 0x31, 0x3b}) {
t.Fatal("go map to mapping did not create correct mapping")
}
}
func TestMappingToMap(t *testing.T) {
mapping := Mapping{0x00, 0x08, 0x61, 0x3d, 0x31, 0x3b, 0x62, 0x3d, 0x32, 0x3b}
gomap := mapping.ToMap()
if gomap["a"] != "1" {
t.Fatal("map does not contain encoded data")
}
if gomap["b"] != "2" {
t.Fatal("map does not comtain encoded data")
}
}
func TestToAndFromMapping(t *testing.T) {
gomap := make(map[string]string)
gomap["foo"] = "bar"
mapping := MappingFromMap(gomap)
gomap2 := mapping.ToMap()
if gomap["foo"] != gomap2["foo"] {
t.Fatal("rebuilt map has different data")
}
}

View File

@ -0,0 +1,57 @@
package common
import (
"bytes"
"encoding/binary"
)
type RouterAddress []byte
func (router_address RouterAddress) Cost() int {
var cost int
buf := bytes.NewReader(
[]byte{router_address[0]},
)
binary.Read(buf, binary.BigEndian, &cost)
return cost
}
func (router_address RouterAddress) Expiration() (d Date) {
copy(router_address[1:8], d[:])
return
}
func (router_address RouterAddress) TransportStyle() string {
return string(
router_address[10:router_address.stringLength()],
)
}
func (router_address RouterAddress) Options() Mapping {
var mapping Mapping
copy(router_address[9+router_address.stringLength():], mapping[:])
return mapping
}
func (router_address RouterAddress) stringLength() int {
var string_len int
buf := bytes.NewReader(
[]byte{router_address[9]},
)
binary.Read(buf, binary.BigEndian, &string_len)
return string_len
}
func readRouterAddress(data []byte) (RouterAddress, []byte, error) {
var router_address RouterAddress
copy(data[:10], router_address)
string_len := router_address.stringLength()
router_address = append(router_address, data[10:10+string_len]...)
options_len := int(binary.BigEndian.Uint16(data[string_len+10 : string_len+11]))
router_address = append(router_address, data[string_len+10:11+string_len+options_len]...)
return router_address, data[:], nil
}

View File

@ -0,0 +1,41 @@
package common
import (
"errors"
"github.com/bounce-chat/go-i2p/lib/crypto"
)
type RouterIdentity []byte
func (router_identity RouterIdentity) PublicKey() (key crypto.ElgPublicKey) {
copy(router_identity[:256], key[:])
return
}
func (router_identity RouterIdentity) SigningPublicKey() (key crypto.SigningPublicKey) {
cert := router_identity.Certificate()
if cert.Type() == CERT_KEY {
key = KeyCert(cert).SigningPublicKey()
} else {
var pk crypto.DSAPublicKey
copy(pk[:], router_identity[256:256+128])
key = pk
}
return
}
func (router_identity RouterIdentity) Certificate() (cert Certificate) {
copy(router_identity[256+128:], cert)
return
}
func readRouterIdentity(data []byte) (RouterIdentity, []byte, error) {
var router_identity RouterIdentity
copy(data[:387], router_identity)
n := router_identity.Certificate().Len()
if n == -1 {
return router_identity, data, errors.New("invalid certificate")
}
router_identity = append(router_identity, data[387:n]...)
return router_identity, data[387+n:], nil
}

77
lib/common/router_info.go Normal file
View File

@ -0,0 +1,77 @@
package common
import (
"bytes"
"encoding/binary"
)
type RouterInfo []byte
func (router_info RouterInfo) RouterIdentity() RouterIdentity {
router_identity, _, _ := readRouterIdentity(router_info)
return router_identity
}
func (router_info RouterInfo) Published() (d Date) {
_, remainder, _ := readRouterIdentity(router_info)
copy(remainder[:8], d[:])
return
}
func (router_info RouterInfo) RouterAddressCount() int {
_, remainder, _ := readRouterIdentity(router_info)
var count int
buf := bytes.NewReader(
[]byte{remainder[8]},
)
binary.Read(buf, binary.BigEndian, &count)
return count
}
func (router_info RouterInfo) RouterAddresses() []RouterAddress {
var router_address RouterAddress
remaining := router_info[9:]
var err error
addresses := make([]RouterAddress, 0)
for i := 0; i < router_info.RouterAddressCount(); i++ {
router_address, remaining, err = readRouterAddress(remaining)
addresses = append(addresses, router_address)
}
return addresses
}
func (router_info RouterInfo) PeerSize() int {
return 0
}
func (router_info RouterInfo) Options() Mapping {
head := router_info.optionsLocation()
size := head + router_info.optionsSize()
return Mapping(router_info[head:size])
}
func (router_info RouterInfo) Signature() []byte {
offset := router_info.optionsLocation() + router_info.optionsSize()
sig_size := router_info.
RouterIdentity().
Certificate().
signatureSize()
return router_info[offset:sig_size]
}
func (router_info RouterInfo) optionsLocation() int {
offset := 9
var router_address RouterAddress
remaining := router_info[9:]
var err error
for i := 0; i < router_info.RouterAddressCount(); i++ {
router_address, remaining, err = readRouterAddress(remaining)
offset := len(router_address)
}
return offset
}
func (router_info RouterInfo) optionsSize() int {
head := router_info.optionsLocation()
return int(binary.BigEndian.Uint16(router_info[head : head+1]))
}