work on router address and router info

This commit is contained in:
Hayden Parker
2016-02-07 02:54:02 -08:00
parent d1699e946e
commit 1af45068d4
10 changed files with 219 additions and 105 deletions

View File

@ -9,15 +9,15 @@ import (
type Destination []byte
func (destination Destination) PublicKey() (key crypto.ElgPublicKey) {
func (destination Destination) PublicKey() (crypto.ElgPublicKey, error) {
return KeysAndCert(destination).PublicKey()
}
func (destination Destination) SigningPublicKey() (key crypto.SigningPublicKey) {
func (destination Destination) SigningPublicKey() (crypto.SigningPublicKey, error) {
return KeysAndCert(destination).SigningPublicKey()
}
func (destination Destination) Certificate() (cert Certificate) {
func (destination Destination) Certificate() (Certificate, error) {
return KeysAndCert(destination).Certificate()
}

View File

@ -1,32 +1,48 @@
package common
import (
"errors"
"github.com/bounce-chat/go-i2p/lib/crypto"
)
type KeysAndCert []byte
func (keys_and_cert KeysAndCert) PublicKey() (key crypto.ElgPublicKey) {
if len(keys_and_cert) < 387 {
func (keys_and_cert KeysAndCert) PublicKey() (key crypto.ElgPublicKey, err error) {
keys_cert_len := len(keys_and_cert)
if keys_cert_len < 387 {
if keys_cert_len < 256 {
err = errors.New("error parsing KeysAndCert: data smaller than ElgPublicKey size")
return
}
err = errors.New("warning parsing KeysAndCert: data is smaller than minimum valid size")
}
copy(keys_and_cert[:256], key[:])
return
}
func (keys_and_cert KeysAndCert) SigningPublicKey() (key crypto.SigningPublicKey) {
cert := keys_and_cert.Certificate()
func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey, err error) {
cert, err := keys_and_cert.Certificate()
switch err.Error() {
case "":
}
if cert.Type() == CERT_KEY {
key = KeyCertificate(cert).SigningPublicKey()
signing_public_key = KeyCertificate(cert).SigningPublicKey()
} else {
var pk crypto.DSAPublicKey
copy(pk[:], keys_and_cert[256:256+128])
key = pk
// Only Key Certificates are currently used:
// https://geti2p.net/en/docs/spec/common-structures#type_Certificate
}
return
}
func (keys_and_cert KeysAndCert) Certificate() (cert Certificate) {
func (keys_and_cert KeysAndCert) Certificate() (cert Certificate, err error) {
keys_cert_len := len(keys_and_cert)
if keys_cert_len < 387 {
if keys_cert_len < 384 {
err = errors.New("error parsing KeysAndCert: data smaller than needed for Certificate")
return
}
err = errors.New("warning parsing KeysAndCert: data is smaller than minimum valid size")
}
copy(keys_and_cert[256+128:], cert)
return
}
@ -34,7 +50,8 @@ func (keys_and_cert KeysAndCert) Certificate() (cert Certificate) {
func ReadKeysAndCert(data []byte) (KeysAndCert, []byte, error) {
var keys_and_cert KeysAndCert
copy(data[:387], keys_and_cert)
n, err := keys_and_cert.Certificate().Length()
cert, _ := keys_and_cert.Certificate()
n, err := cert.Length()
if err != nil {
return keys_and_cert, data, err
}

View File

@ -4,11 +4,7 @@ import (
"github.com/bounce-chat/go-i2p/lib/tunnel"
)
const (
LEASE_SIZE = 44
)
type Lease [LEASE_SIZE]byte
type Lease [44]byte
func (lease Lease) TunnelGateway() (h Hash) {
copy(lease[:32], h[:])

View File

@ -7,7 +7,7 @@ import (
type LeaseSet []byte
func (lease_set LeaseSet) Destination() Destination {
return Destination(lease_set[:387])
return Destination(lease_set[:387]) // read a keys and cert, cast to destination
}
func (lease_set LeaseSet) EncryptionKey() (k crypto.ElgPublicKey) {
@ -31,8 +31,8 @@ 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)
start := offset + (i * 44)
end := offset + (start + 44)
var lease Lease
copy(lease_set[start:end], lease[:])
leases = append(leases, lease)
@ -45,11 +45,11 @@ func (lease_set LeaseSet) Signature() []byte {
256 +
lease_set.signingKeySize() +
1 +
(LEASE_SIZE * lease_set.LeaseCount())
sig_size := lease_set.
(44 * lease_set.LeaseCount())
sig_cert, _ := lease_set.
Destination().
Certificate().
SignatureSize()
Certificate()
sig_size := sig_cert.SignatureSize()
return lease_set[data_end : data_end+sig_size]
}
@ -58,12 +58,12 @@ func (lease_set LeaseSet) Verify() error {
256 +
lease_set.signingKeySize() +
1 +
(LEASE_SIZE * lease_set.LeaseCount())
(44 * lease_set.LeaseCount())
data := lease_set[:data_end]
verifier, err := lease_set.
spk, _ := lease_set.
Destination().
SigningPublicKey().
NewVerifier()
SigningPublicKey()
verifier, err := spk.NewVerifier()
if err != nil {
return err
}
@ -71,8 +71,8 @@ func (lease_set LeaseSet) Verify() error {
}
func (lease_set LeaseSet) signingKeySize() int {
return lease_set.
spk, _ := lease_set.
Destination().
SigningPublicKey().
Len()
SigningPublicKey()
return spk.Len()
}

View File

@ -1 +0,0 @@
package common

View File

@ -1,41 +1,103 @@
package common
import (
"errors"
)
type RouterAddress []byte
func (router_address RouterAddress) Cost() int {
return Integer([]byte{router_address[0]})
}
func (router_address RouterAddress) Expiration() (d Date) {
copy(router_address[1:8], d[:])
//
// Return the cost integer for this RouterAddress and any errors
// encountered parsing the RouterAddress.
//
func (router_address RouterAddress) Cost() (cost int, err error) {
verr, exit := router_address.checkRouterAddressValid()
err = verr
if exit {
return
}
cost = Integer([]byte{router_address[0]})
return
}
func (router_address RouterAddress) TransportStyle() string {
return string( //String
router_address[10:router_address.stringLength()],
)
//
// Return the Date this RouterAddress expires and any errors
// encountered parsing the RouterAddress.
//
func (router_address RouterAddress) Expiration() (date Date, err error) {
verr, exit := router_address.checkRouterAddressValid()
err = verr
if exit {
return
}
copy(router_address[1:8], date[:])
return
}
func (router_address RouterAddress) Options() Mapping {
var mapping Mapping
copy(router_address[9+router_address.stringLength():], mapping[:])
return mapping
//
// Return the Transport type for this RouterAddress expire
// and any errors encountered parsing the RouterAddress.
//
//
func (router_address RouterAddress) TransportStyle() (str String, err error) {
verr, exit := router_address.checkRouterAddressValid()
err = verr
if exit {
return
}
str, _, err = ReadString(router_address[9:])
return
}
func (router_address RouterAddress) stringLength() int {
return Integer([]byte{router_address[9]})
//
// Return the Mapping containing the options for this
// RouterAddress and any parsing errors.
//
func (router_address RouterAddress) Options() (mapping Mapping, err error) {
verr, exit := router_address.checkRouterAddressValid()
err = verr
if exit {
return
}
_, remainder, _ := ReadString(router_address[9:])
if len(remainder) == 0 {
return
}
mapping = Mapping(remainder)
return
}
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 := Integer(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
//
// Check if the RouterAddress is empty or if it is too small
// to contain valid data
//
func (router_address RouterAddress) checkRouterAddressValid() (err error, exit bool) {
addr_len := len(router_address)
exit = false
if len(router_address) == 0 {
err = errors.New("error parsing RouterAddress: no data")
exit = true
}
if addr_len < 9 {
err = errors.New("warning parsing RouterAddress: data too small")
}
return
}
//
// Given a slice of bytes, read a RouterAddress, returning the remaining
// bytes and any errors encountered parsing the RouterAddress
//
func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []byte, err error) {
test_address := RouterAddress(data)
err, _ = test_address.checkRouterAddressValid()
if err != nil {
return
}
ops, rerr := test_address.Options()
err = rerr
ops_len := len(ops)
router_address = RouterAddress(data[:9+ops_len])
remainder = data[9+ops_len:]
return
}

View File

@ -6,15 +6,15 @@ import (
type RouterIdentity []byte
func (router_identity RouterIdentity) PublicKey() (key crypto.ElgPublicKey) {
func (router_identity RouterIdentity) PublicKey() (crypto.ElgPublicKey, error) {
return KeysAndCert(router_identity).PublicKey()
}
func (router_identity RouterIdentity) SigningPublicKey() (key crypto.SigningPublicKey) {
func (router_identity RouterIdentity) SigningPublicKey() (crypto.SigningPublicKey, error) {
return KeysAndCert(router_identity).SigningPublicKey()
}
func (router_identity RouterIdentity) Certificate() (cert Certificate) {
func (router_identity RouterIdentity) Certificate() (Certificate, error) {
return KeysAndCert(router_identity).Certificate()
}

View File

@ -1,67 +1,121 @@
package common
import (
"errors"
)
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[:])
//
// Read a RouterIdentity from the RouterInfo, returning the
// RouterIdentity and any parsing errors.
//
func (router_info RouterInfo) RouterIdentity() (router_identity RouterIdentity, err error) {
router_identity, _, err = ReadRouterIdentity(router_info)
return
}
func (router_info RouterInfo) RouterAddressCount() int {
//
// Return the Date the RouterInfo was published and any errors
// encountered parsing the RouterInfo.
//
func (router_info RouterInfo) Published() (date Date, err error) {
_, remainder, _ := ReadRouterIdentity(router_info)
return Integer([]byte{remainder[8]})
if len(remainder) < 8 {
err = errors.New("")
return
}
copy(remainder[:8], date[:])
return
}
func (router_info RouterInfo) RouterAddresses() []RouterAddress {
var router_address RouterAddress
//
// Return the Integer representing the number of RouterAddresses
// are contained in this RouterInfo.
//
func (router_info RouterInfo) RouterAddressCount() (count int, err error) {
_, remainder, _ := ReadRouterIdentity(router_info)
if len(remainder) < 9 {
err = errors.New("")
return
}
count = Integer([]byte{remainder[8]})
return
}
//
// Read the RouterAddresses inside this RouterInfo and return
// them in a slice.
//
func (router_info RouterInfo) RouterAddresses() (router_addresses []RouterAddress, err error) {
_, remainder, _ := ReadRouterIdentity(router_info)
if len(remainder) < 9 {
err = errors.New("")
return
}
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)
var router_address RouterAddress
addr_count, cerr := router_info.RouterAddressCount()
if cerr != nil {
err = cerr
return
}
for i := 0; i < addr_count; i++ {
router_address, remaining, err = ReadRouterAddress(remaining)
if err == nil {
addresses = append(addresses, router_address)
router_addresses = append(router_addresses, router_address)
}
}
return addresses
return
}
//
// Return the PeerSize value, currently unused and always zero.
//
func (router_info RouterInfo) PeerSize() int {
// Peer size is unused:
// https://geti2p.net/en/docs/spec/common-structures#struct_RouterAddress
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()
router_identity, _ := router_info.RouterIdentity()
cert, _ := router_identity.Certificate()
sig_size := cert.SignatureSize()
return router_info[offset:sig_size]
}
//
//
//
func (router_info RouterInfo) optionsLocation() int {
offset := 9
var router_address RouterAddress
remaining := router_info[9:]
for i := 0; i < router_info.RouterAddressCount(); i++ {
router_address, remaining, _ = readRouterAddress(remaining)
offset = len(router_address)
addr_count, _ := router_info.RouterAddressCount()
for i := 0; i < addr_count; i++ {
router_address, remaining, _ = ReadRouterAddress(remaining)
offset += len(router_address)
}
return offset
}
//
//
//
func (router_info RouterInfo) optionsSize() int {
head := router_info.optionsLocation()
return Integer(router_info[head : head+1])

View File

@ -1,14 +0,0 @@
package common
import (
"os"
)
// check if a file is there and writeable
func FileExists(fname string) (exists bool) {
_, err := os.Stat(fname)
if err == nil {
exists = true
}
return
}

View File

@ -1,7 +1,6 @@
package netdb
import (
"github.com/bounce-chat/go-i2p/lib/common"
log "github.com/golang/glog"
"io"
"os"
@ -24,7 +23,8 @@ func (db StdNetDB) KnownPeerCount() (routers int) {
// return true if the network db directory exists and is writable
func (db StdNetDB) Exists() bool {
return common.FileExists(db.Path())
_, err := os.Stat(db.Path())
return err != nil
}
func (db StdNetDB) SaveEntry(e *Entry) (err error) {