mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-07-05 06:05:16 -04:00
adding logging, headers, godoc to common data structures
This commit is contained in:
@ -42,7 +42,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CERT_MIN_LENGTH = 3
|
CERT_MIN_SIZE = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
type Certificate []byte
|
type Certificate []byte
|
||||||
@ -53,10 +53,10 @@ type Certificate []byte
|
|||||||
//
|
//
|
||||||
func (certificate Certificate) Type() (cert_type int, err error) {
|
func (certificate Certificate) Type() (cert_type int, err error) {
|
||||||
cert_len := len(certificate)
|
cert_len := len(certificate)
|
||||||
if cert_len < CERT_MIN_LENGTH {
|
if cert_len < CERT_MIN_SIZE {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"certificate_bytes_length": cert_len,
|
"certificate_bytes_length": cert_len,
|
||||||
"reason": "too short (len < CERT_MIN_LENGTH)",
|
"reason": "too short (len < CERT_MIN_SIZE)",
|
||||||
}).Error("invalid certificate")
|
}).Error("invalid certificate")
|
||||||
err = errors.New("error parsing certificate length: certificate is too short")
|
err = errors.New("error parsing certificate length: certificate is too short")
|
||||||
return
|
return
|
||||||
@ -76,8 +76,8 @@ func (certificate Certificate) Length() (length int, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
length = Integer(certificate[1:CERT_MIN_LENGTH])
|
length = Integer(certificate[1:CERT_MIN_SIZE])
|
||||||
inferred_len := length + CERT_MIN_LENGTH
|
inferred_len := length + CERT_MIN_SIZE
|
||||||
if inferred_len > cert_len {
|
if inferred_len > cert_len {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"certificate_bytes_length": cert_len,
|
"certificate_bytes_length": cert_len,
|
||||||
@ -108,14 +108,14 @@ func (certificate Certificate) Data() (data []byte, err error) {
|
|||||||
case "error parsing certificate length: certificate is too short":
|
case "error parsing certificate length: certificate is too short":
|
||||||
return
|
return
|
||||||
case "certificate parsing warning: certificate data is shorter than specified by length":
|
case "certificate parsing warning: certificate data is shorter than specified by length":
|
||||||
data = certificate[CERT_MIN_LENGTH:]
|
data = certificate[CERT_MIN_SIZE:]
|
||||||
return
|
return
|
||||||
case "certificate parsing warning: certificate contains data beyond length":
|
case "certificate parsing warning: certificate contains data beyond length":
|
||||||
data = certificate[CERT_MIN_LENGTH : length+CERT_MIN_LENGTH]
|
data = certificate[CERT_MIN_SIZE : length+CERT_MIN_SIZE]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data = certificate[CERT_MIN_LENGTH:]
|
data = certificate[CERT_MIN_SIZE:]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,8 +127,8 @@ func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, er
|
|||||||
certificate = Certificate(data)
|
certificate = Certificate(data)
|
||||||
length, err := certificate.Length()
|
length, err := certificate.Length()
|
||||||
if err != nil && err.Error() == "certificate parsing warning: certificate contains data beyond length" {
|
if err != nil && err.Error() == "certificate parsing warning: certificate contains data beyond length" {
|
||||||
certificate = Certificate(data[:length+CERT_MIN_LENGTH])
|
certificate = Certificate(data[:length+CERT_MIN_SIZE])
|
||||||
remainder = data[length+CERT_MIN_LENGTH:]
|
remainder = data[length+CERT_MIN_SIZE:]
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -8,6 +8,7 @@ Accurate for version 0.9.24
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/bounce-chat/go-i2p/lib/crypto"
|
"github.com/bounce-chat/go-i2p/lib/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,25 +48,37 @@ const (
|
|||||||
KEYCERT_CRYPTO_ELG_SIZE = 256
|
KEYCERT_CRYPTO_ELG_SIZE = 256
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KEYCERT_PUBKEY_SIZE = 256
|
||||||
|
KEYCERT_SPK_SIZE = 128
|
||||||
|
)
|
||||||
|
|
||||||
type KeyCertificate []byte
|
type KeyCertificate []byte
|
||||||
|
|
||||||
//
|
//
|
||||||
// The data contained in the Certificate.
|
// The data contained in the Key Certificate.
|
||||||
//
|
//
|
||||||
func (key_certificate KeyCertificate) Data() ([]byte, error) {
|
func (key_certificate KeyCertificate) Data() ([]byte, error) {
|
||||||
return Certificate(key_certificate).Data()
|
return Certificate(key_certificate).Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
// The SigningPublicKey type this Key Certificate describes and any errors encountered
|
||||||
|
// parsing the KeyCertificate.
|
||||||
//
|
//
|
||||||
func (key_certificate KeyCertificate) SigningPublicKeyType() (signing_pubkey_type int, err error) {
|
func (key_certificate KeyCertificate) SigningPublicKeyType() (signing_pubkey_type int, err error) {
|
||||||
data, err := key_certificate.Data()
|
data, err := key_certificate.Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data) < 2 {
|
data_len := len(data)
|
||||||
err = errors.New("")
|
if data_len < 2 {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": data_len,
|
||||||
|
"required_len": 2,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing key certificate")
|
||||||
|
err = errors.New("error parsing key certificate: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
signing_pubkey_type = Integer(data[:2])
|
signing_pubkey_type = Integer(data[:2])
|
||||||
@ -73,15 +86,22 @@ func (key_certificate KeyCertificate) SigningPublicKeyType() (signing_pubkey_typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
// The PublicKey type this Key Certificate describes and any errors encountered parsing
|
||||||
|
// this KeyCertificate.
|
||||||
//
|
//
|
||||||
func (key_certificate KeyCertificate) PublicKeyType() (pubkey_type int, err error) {
|
func (key_certificate KeyCertificate) PublicKeyType() (pubkey_type int, err error) {
|
||||||
data, err := key_certificate.Data()
|
data, err := key_certificate.Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data) < 4 {
|
data_len := len(data)
|
||||||
err = errors.New("")
|
if data_len < 4 {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": data_len,
|
||||||
|
"required_len": 4,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing key certificate")
|
||||||
|
err = errors.New("error parsing key certificate: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pubkey_type = Integer(data[2:4])
|
pubkey_type = Integer(data[2:4])
|
||||||
@ -89,56 +109,70 @@ func (key_certificate KeyCertificate) PublicKeyType() (pubkey_type int, err erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
// Given some bytes, build a PublicKey using any excess data that may be stored in the KeyCertificate and return
|
||||||
|
// it along with any errors encountered constructing the PublicKey.
|
||||||
//
|
//
|
||||||
func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_key crypto.PublicKey, err error) {
|
func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_key crypto.PublicKey, err error) {
|
||||||
key_type, err := key_certificate.PublicKeyType()
|
key_type, err := key_certificate.PublicKeyType()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data) < 256 {
|
data_len := len(data)
|
||||||
err = errors.New("")
|
if data_len < KEYCERT_PUBKEY_SIZE {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": data_len,
|
||||||
|
"required_len": KEYCERT_PUBKEY_SIZE,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error constructing public key")
|
||||||
|
err = errors.New("error constucting public key: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch key_type {
|
switch key_type {
|
||||||
case KEYCERT_CRYPTO_ELG:
|
case KEYCERT_CRYPTO_ELG:
|
||||||
var elg_key crypto.ElgPublicKey
|
var elg_key crypto.ElgPublicKey
|
||||||
copy(elg_key[:], data[256-KEYCERT_CRYPTO_ELG_SIZE:256])
|
copy(elg_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
||||||
public_key = elg_key
|
public_key = elg_key
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
// Given some bytes, build a SigningPublicKey using any excess data that may be stored in the KeyCertificate and return
|
||||||
|
// it along with any errors encountered constructing the SigningPublicKey.
|
||||||
//
|
//
|
||||||
func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (signing_public_key crypto.SigningPublicKey) {
|
func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (signing_public_key crypto.SigningPublicKey) {
|
||||||
signing_key_type, err := key_certificate.PublicKeyType()
|
signing_key_type, err := key_certificate.PublicKeyType()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data) < 128 {
|
data_len := len(data)
|
||||||
err = errors.New("")
|
if data_len < KEYCERT_SPK_SIZE {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": data_len,
|
||||||
|
"required_len": KEYCERT_SPK_SIZE,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error constructing signing public key")
|
||||||
|
err = errors.New("error constucting signing public key: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch signing_key_type {
|
switch signing_key_type {
|
||||||
case KEYCERT_SIGN_DSA_SHA1:
|
case KEYCERT_SIGN_DSA_SHA1:
|
||||||
var dsa_key crypto.DSAPublicKey
|
var dsa_key crypto.DSAPublicKey
|
||||||
copy(dsa_key[:], data[128-KEYCERT_SIGN_DSA_SHA1_SIZE:128])
|
copy(dsa_key[:], data[KEYCERT_SPK_SIZE-KEYCERT_SIGN_DSA_SHA1_SIZE:KEYCERT_SPK_SIZE])
|
||||||
signing_public_key = dsa_key
|
signing_public_key = dsa_key
|
||||||
case KEYCERT_SIGN_P256:
|
case KEYCERT_SIGN_P256:
|
||||||
var ec_key crypto.ECP256PublicKey
|
var ec_key crypto.ECP256PublicKey
|
||||||
copy(ec_key[:], data[128-KEYCERT_SIGN_P256_SIZE:128])
|
copy(ec_key[:], data[KEYCERT_SPK_SIZE-KEYCERT_SIGN_P256_SIZE:KEYCERT_SPK_SIZE])
|
||||||
signing_public_key = ec_key
|
signing_public_key = ec_key
|
||||||
case KEYCERT_SIGN_P384:
|
case KEYCERT_SIGN_P384:
|
||||||
var ec_key crypto.ECP384PublicKey
|
var ec_key crypto.ECP384PublicKey
|
||||||
copy(ec_key[:], data[128-KEYCERT_SIGN_P384_SIZE:128])
|
copy(ec_key[:], data[KEYCERT_SPK_SIZE-KEYCERT_SIGN_P384_SIZE:KEYCERT_SPK_SIZE])
|
||||||
signing_public_key = ec_key
|
signing_public_key = ec_key
|
||||||
case KEYCERT_SIGN_P521:
|
case KEYCERT_SIGN_P521:
|
||||||
var ec_key crypto.ECP521PublicKey
|
var ec_key crypto.ECP521PublicKey
|
||||||
extra := KEYCERT_SIGN_P521_SIZE - 128
|
extra := KEYCERT_SIGN_P521_SIZE - KEYCERT_SPK_SIZE
|
||||||
copy(ec_key[:], data)
|
copy(ec_key[:], data)
|
||||||
copy(ec_key[128:], key_certificate[4:4+extra])
|
copy(ec_key[KEYCERT_SPK_SIZE:], key_certificate[4:4+extra])
|
||||||
signing_public_key = ec_key
|
signing_public_key = ec_key
|
||||||
case KEYCERT_SIGN_RSA2048:
|
case KEYCERT_SIGN_RSA2048:
|
||||||
//var rsa_key crypto.RSA2048PublicKey
|
//var rsa_key crypto.RSA2048PublicKey
|
||||||
@ -154,6 +188,10 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the size of a Signature corresponding to the Key Certificate's
|
||||||
|
// SigningPublicKey type.
|
||||||
|
//
|
||||||
func (key_certificate KeyCertificate) SignatureSize() (size int) {
|
func (key_certificate KeyCertificate) SignatureSize() (size int) {
|
||||||
sizes := map[int]int{
|
sizes := map[int]int{
|
||||||
KEYCERT_SIGN_DSA_SHA1: 40,
|
KEYCERT_SIGN_DSA_SHA1: 40,
|
||||||
|
@ -1,15 +1,67 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
|
/*
|
||||||
|
I2P KeysAndCert
|
||||||
|
https://geti2p.net/en/docs/spec/common-structures#struct_KeysAndCert
|
||||||
|
Accurate for version 0.9.24
|
||||||
|
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| public_key |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| padding (optional) |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| signing_key |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| certificate |
|
||||||
|
+----+----+----+-//
|
||||||
|
|
||||||
|
public_key :: PublicKey (partial or full)
|
||||||
|
length -> 256 bytes or as specified in key certificate
|
||||||
|
|
||||||
|
padding :: random data
|
||||||
|
length -> 0 bytes or as specified in key certificate
|
||||||
|
padding length + signing_key length == KEYS_AND_CERT_SPK_SIZE bytes
|
||||||
|
|
||||||
|
signing__key :: SigningPublicKey (partial or full)
|
||||||
|
length -> 128 bytes or as specified in key certificate
|
||||||
|
padding length + signing_key length == KEYS_AND_CERT_SPK_SIZE bytes
|
||||||
|
|
||||||
|
certificate :: Certificate
|
||||||
|
length -> >= 3 bytes
|
||||||
|
|
||||||
|
total length: 387+ bytes
|
||||||
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/bounce-chat/go-i2p/lib/crypto"
|
"github.com/bounce-chat/go-i2p/lib/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KEYS_AND_CERT_PUBKEY_SIZE = 256
|
||||||
|
KEYS_AND_CERT_SPK_SIZE = 128
|
||||||
|
KEYS_AND_CERT_MIN_SIZE = 387
|
||||||
|
)
|
||||||
|
|
||||||
type KeysAndCert []byte
|
type KeysAndCert []byte
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return the ElgPublicKey for this KeysAndCert, reading from the Key Certificate
|
// Return the PublicKey for this KeysAndCert, reading from the Key Certificate if it is present to
|
||||||
// if it is present first, then the first 256 bytes of the KeysAndCert.
|
// determine correct lengths.
|
||||||
//
|
//
|
||||||
func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
|
func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
|
||||||
cert, err := keys_and_cert.Certificate()
|
cert, err := keys_and_cert.Certificate()
|
||||||
@ -18,10 +70,10 @@ func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cert_len == 0 {
|
if cert_len == 0 {
|
||||||
// No Certificate is present, return the 256 byte
|
// No Certificate is present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
|
||||||
// PublicKey space as ElgPublicKey.
|
// PublicKey space as ElgPublicKey.
|
||||||
var elg_key crypto.ElgPublicKey
|
var elg_key crypto.ElgPublicKey
|
||||||
copy(keys_and_cert[:256], elg_key[:])
|
copy(keys_and_cert[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
|
||||||
key = elg_key
|
key = elg_key
|
||||||
} else {
|
} else {
|
||||||
// A Certificate is present in this KeysAndCert
|
// A Certificate is present in this KeysAndCert
|
||||||
@ -30,13 +82,15 @@ func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
|
|||||||
// This KeysAndCert contains a Key Certificate, construct
|
// This KeysAndCert contains a Key Certificate, construct
|
||||||
// a PublicKey from the data in the KeysAndCert and
|
// a PublicKey from the data in the KeysAndCert and
|
||||||
// any additional data in the Certificate.
|
// any additional data in the Certificate.
|
||||||
key, err = KeyCertificate(cert).ConstructPublicKey(keys_and_cert[:256])
|
key, err = KeyCertificate(cert).ConstructPublicKey(
|
||||||
|
keys_and_cert[:KEYS_AND_CERT_PUBKEY_SIZE],
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// Key Certificate is not present, return the 256 byte
|
// Key Certificate is not present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
|
||||||
// PublicKey space as ElgPublicKey. No other Certificate
|
// PublicKey space as ElgPublicKey. No other Certificate
|
||||||
// types are currently in use
|
// types are currently in use
|
||||||
var elg_key crypto.ElgPublicKey
|
var elg_key crypto.ElgPublicKey
|
||||||
copy(keys_and_cert[:256], elg_key[:])
|
copy(keys_and_cert[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
|
||||||
key = elg_key
|
key = elg_key
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,8 +99,8 @@ func (keys_and_cert KeysAndCert) PublicKey() (key crypto.PublicKey, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return the SigningPublicKey for this KeysAndCert, reading from the Key Certificate
|
// Return the SigningPublicKey for this KeysAndCert, reading from the Key Certificate if it is present to
|
||||||
// if it is present first, then the SigningPublicKey space in the KeysAndCert.
|
// determine correct lengths.
|
||||||
//
|
//
|
||||||
func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey, err error) {
|
func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey, err error) {
|
||||||
cert, err := keys_and_cert.Certificate()
|
cert, err := keys_and_cert.Certificate()
|
||||||
@ -55,10 +109,10 @@ func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.S
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cert_len == 0 {
|
if cert_len == 0 {
|
||||||
// No Certificate is present, return the 128 byte
|
// No Certificate is present, return the KEYS_AND_CERT_SPK_SIZE byte
|
||||||
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
||||||
var dsa_pk crypto.DSAPublicKey
|
var dsa_pk crypto.DSAPublicKey
|
||||||
copy(dsa_pk[:], keys_and_cert[256:256+128])
|
copy(dsa_pk[:], keys_and_cert[KEYS_AND_CERT_PUBKEY_SIZE:KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE])
|
||||||
signing_public_key = dsa_pk
|
signing_public_key = dsa_pk
|
||||||
} else {
|
} else {
|
||||||
// A Certificate is present in this KeysAndCert
|
// A Certificate is present in this KeysAndCert
|
||||||
@ -67,13 +121,15 @@ func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.S
|
|||||||
// This KeysAndCert contains a Key Certificate, construct
|
// This KeysAndCert contains a Key Certificate, construct
|
||||||
// a SigningPublicKey from the data in the KeysAndCert and
|
// a SigningPublicKey from the data in the KeysAndCert and
|
||||||
// any additional data in the Certificate.
|
// any additional data in the Certificate.
|
||||||
signing_public_key = KeyCertificate(cert).ConstructSigningPublicKey(keys_and_cert[256 : 256+128])
|
signing_public_key = KeyCertificate(cert).ConstructSigningPublicKey(
|
||||||
|
keys_and_cert[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE],
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// Key Certificate is not present, return the 128 byte
|
// Key Certificate is not present, return the KEYS_AND_CERT_SPK_SIZE byte
|
||||||
// SigningPublicKey space as legacy SHA DSA1 SigningPublicKey.
|
// SigningPublicKey space as legacy SHA DSA1 SigningPublicKey.
|
||||||
// No other Certificate types are currently in use.
|
// No other Certificate types are currently in use.
|
||||||
var dsa_pk crypto.DSAPublicKey
|
var dsa_pk crypto.DSAPublicKey
|
||||||
copy(dsa_pk[:], keys_and_cert[256:256+128])
|
copy(dsa_pk[:], keys_and_cert[KEYS_AND_CERT_PUBKEY_SIZE:KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE])
|
||||||
signing_public_key = dsa_pk
|
signing_public_key = dsa_pk
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,35 +138,47 @@ func (keys_and_cert KeysAndCert) SigningPublicKey() (signing_public_key crypto.S
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return the Certificate cointained in the KeysAndCert and errors encountered
|
// Return the Certificate contained in the KeysAndCert and any errors encountered while parsing the
|
||||||
// while parsing the KeysAndCert or Certificate.
|
// KeysAndCert or Certificate.
|
||||||
//
|
//
|
||||||
func (keys_and_cert KeysAndCert) Certificate() (cert Certificate, err error) {
|
func (keys_and_cert KeysAndCert) Certificate() (cert Certificate, err error) {
|
||||||
keys_cert_len := len(keys_and_cert)
|
keys_cert_len := len(keys_and_cert)
|
||||||
if keys_cert_len < 387 {
|
if keys_cert_len < KEYS_AND_CERT_MIN_SIZE {
|
||||||
err = errors.New("warning parsing KeysAndCert: data is smaller than minimum valid size")
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": keys_cert_len,
|
||||||
|
"required_len": KEYS_AND_CERT_MIN_SIZE,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing keys and cert")
|
||||||
|
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cert, _, err = ReadCertificate(keys_and_cert[256+128:])
|
cert, _, err = ReadCertificate(keys_and_cert[KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
// Read a KeysAndCert from a slice of bytes, retuning it and the remaining data as well as any errors
|
||||||
|
// encoutered parsing the KeysAndCert.
|
||||||
//
|
//
|
||||||
func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) {
|
func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) {
|
||||||
if len(data) < 387 {
|
data_len := len(data)
|
||||||
|
if data_len < KEYS_AND_CERT_MIN_SIZE {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": data_len,
|
||||||
|
"required_len": KEYS_AND_CERT_MIN_SIZE,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing keys and cert")
|
||||||
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
|
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
copy(data[:387], keys_and_cert)
|
copy(data[:KEYS_AND_CERT_MIN_SIZE], keys_and_cert)
|
||||||
cert, _ := keys_and_cert.Certificate()
|
cert, _ := keys_and_cert.Certificate()
|
||||||
n, err := cert.Length()
|
n, err := cert.Length()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remainder = data[387:]
|
remainder = data[KEYS_AND_CERT_MIN_SIZE:]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
keys_and_cert = append(keys_and_cert, data[387:n+3]...)
|
keys_and_cert = append(keys_and_cert, data[KEYS_AND_CERT_MIN_SIZE:n+3]...)
|
||||||
remainder = data[387+n+3:]
|
remainder = data[KEYS_AND_CERT_MIN_SIZE+n+3:]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,138 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
|
/*
|
||||||
|
I2P LeaseSet
|
||||||
|
https://geti2p.net/en/docs/spec/common-structures#struct_LeaseSet
|
||||||
|
Accurate for version 0.9.24
|
||||||
|
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| destination |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| encryption_key |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| signing_key |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
|num | Lease 0 |
|
||||||
|
+----+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| Lease 1 |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| Lease ($num-1) |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
~ ~
|
||||||
|
~ ~
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
| signature |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
|
||||||
|
destination :: Destination
|
||||||
|
length -> >= 387 bytes
|
||||||
|
|
||||||
|
encryption_key :: PublicKey
|
||||||
|
length -> 256 bytes
|
||||||
|
|
||||||
|
signing_key :: SigningPublicKey
|
||||||
|
length -> 128 bytes or as specified in destination's key certificate
|
||||||
|
|
||||||
|
num :: Integer
|
||||||
|
length -> 1 byte
|
||||||
|
Number of leases to follow
|
||||||
|
value: 0 <= num <= 16
|
||||||
|
|
||||||
|
leases :: [Lease]
|
||||||
|
length -> $num*44 bytes
|
||||||
|
|
||||||
|
signature :: Signature
|
||||||
|
length -> 40 bytes or as specified in destination's key certificate
|
||||||
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/bounce-chat/go-i2p/lib/crypto"
|
"github.com/bounce-chat/go-i2p/lib/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LEASE_SET_PUBKEY_SIZE = 256
|
||||||
|
LEASE_SET_SPK_SIZE = 128
|
||||||
|
LEASE_SET_SIG_SIZE = 40
|
||||||
|
)
|
||||||
|
|
||||||
type LeaseSet []byte
|
type LeaseSet []byte
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read a Destination from the LeaseSet.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
||||||
keys_and_cert, _, err := ReadKeysAndCert(lease_set)
|
keys_and_cert, _, err := ReadKeysAndCert(lease_set)
|
||||||
destination = Destination(keys_and_cert)
|
destination = Destination(keys_and_cert)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the PublicKey in this LeaseSet and any errors ancountered parsing the LeaseSet.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error) {
|
func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error) {
|
||||||
_, remainder, err := ReadKeysAndCert(lease_set)
|
_, remainder, err := ReadKeysAndCert(lease_set)
|
||||||
if len(remainder) < 256 {
|
remainder_len := len(remainder)
|
||||||
|
if remainder_len < LEASE_SET_PUBKEY_SIZE {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": remainder_len,
|
||||||
|
"required_len": LEASE_SET_PUBKEY_SIZE,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing public key")
|
||||||
err = errors.New("error parsing public key: not enough data")
|
err = errors.New("error parsing public key: not enough data")
|
||||||
copy(public_key[:], remainder)
|
copy(public_key[:], remainder)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
copy(public_key[:], remainder[:256])
|
copy(public_key[:], remainder[:LEASE_SET_PUBKEY_SIZE])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the SigningPublicKey, as specified in the LeaseSet's Destination's Key Certificate if
|
||||||
|
// present, or a legacy DSA key.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicKey, err error) {
|
func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicKey, err error) {
|
||||||
destination, err := lease_set.Destination()
|
destination, err := lease_set.Destination()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
offset := len(destination) + 256
|
offset := len(destination) + LEASE_SET_PUBKEY_SIZE
|
||||||
cert, err := destination.Certificate()
|
cert, err := destination.Certificate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -38,15 +141,21 @@ func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicK
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(lease_set) < offset+128 {
|
lease_set_len := len(lease_set)
|
||||||
err = errors.New("")
|
if lease_set_len < offset+LEASE_SET_SPK_SIZE {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": lease_set_len,
|
||||||
|
"required_len": offset + LEASE_SET_SPK_SIZE,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing signing public key")
|
||||||
|
err = errors.New("error parsing signing public key: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cert_len == 0 {
|
if cert_len == 0 {
|
||||||
// No Certificate is present, return the 128 byte
|
// No Certificate is present, return the LEASE_SET_SPK_SIZE byte
|
||||||
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
||||||
var dsa_pk crypto.DSAPublicKey
|
var dsa_pk crypto.DSAPublicKey
|
||||||
copy(dsa_pk[:], lease_set[offset:offset+128])
|
copy(dsa_pk[:], lease_set[offset:offset+LEASE_SET_SPK_SIZE])
|
||||||
signing_public_key = dsa_pk
|
signing_public_key = dsa_pk
|
||||||
} else {
|
} else {
|
||||||
// A Certificate is present in this LeaseSet's Destination
|
// A Certificate is present in this LeaseSet's Destination
|
||||||
@ -55,12 +164,14 @@ func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicK
|
|||||||
// This LeaseSet's Destination's Certificate is a Key Certificate,
|
// This LeaseSet's Destination's Certificate is a Key Certificate,
|
||||||
// create the signing publickey key using any data that might be
|
// create the signing publickey key using any data that might be
|
||||||
// contained in the key certificate.
|
// contained in the key certificate.
|
||||||
signing_public_key = KeyCertificate(cert).ConstructSigningPublicKey(lease_set[offset : offset+128])
|
signing_public_key = KeyCertificate(cert).ConstructSigningPublicKey(
|
||||||
|
lease_set[offset : offset+LEASE_SET_SPK_SIZE],
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// No Certificate is present, return the 128 byte
|
// No Certificate is present, return the LEASE_SET_SPK_SIZE byte
|
||||||
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
||||||
var dsa_pk crypto.DSAPublicKey
|
var dsa_pk crypto.DSAPublicKey
|
||||||
copy(dsa_pk[:], lease_set[offset:offset+128])
|
copy(dsa_pk[:], lease_set[offset:offset+LEASE_SET_SPK_SIZE])
|
||||||
signing_public_key = dsa_pk
|
signing_public_key = dsa_pk
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,34 +179,52 @@ func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicK
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the number of Leases specified by the LeaseCount value in this LeaseSet.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) LeaseCount() (count int, err error) {
|
func (lease_set LeaseSet) LeaseCount() (count int, err error) {
|
||||||
_, remainder, err := ReadKeysAndCert(lease_set)
|
_, remainder, err := ReadKeysAndCert(lease_set)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(remainder) < 256+128+1 {
|
remainder_len := len(remainder)
|
||||||
|
if remainder_len < LEASE_SET_PUBKEY_SIZE+LEASE_SET_SPK_SIZE+1 {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": remainder_len,
|
||||||
|
"required_len": LEASE_SET_PUBKEY_SIZE + LEASE_SET_SPK_SIZE + 1,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing lease count")
|
||||||
err = errors.New("error parsing lease count: not enough data")
|
err = errors.New("error parsing lease count: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
count = Integer([]byte{remainder[256+128]})
|
count = Integer([]byte{remainder[LEASE_SET_PUBKEY_SIZE+LEASE_SET_SPK_SIZE]})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the Leases in this LeaseSet, returning a partial set if there is insufficient data.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) Leases() (leases []Lease, err error) {
|
func (lease_set LeaseSet) Leases() (leases []Lease, err error) {
|
||||||
destination, err := lease_set.Destination()
|
destination, err := lease_set.Destination()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
offset := len(destination) + 256 + 128 + 1
|
offset := len(destination) + LEASE_SET_PUBKEY_SIZE + LEASE_SET_SPK_SIZE + 1
|
||||||
count, err := lease_set.LeaseCount()
|
count, err := lease_set.LeaseCount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
start := offset + (i * 44)
|
start := offset + (i * LEASE_SIZE)
|
||||||
end := start + 44
|
end := start + LEASE_SIZE
|
||||||
if len(lease_set) < end {
|
lease_set_len := len(lease_set)
|
||||||
err = errors.New("")
|
if lease_set_len < end {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": lease_set_len,
|
||||||
|
"required_len": end,
|
||||||
|
"reason": "some leases missing",
|
||||||
|
}).Error("error parsnig lease set")
|
||||||
|
err = errors.New("error parsing lease set: some leases missing")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var lease Lease
|
var lease Lease
|
||||||
@ -105,6 +234,10 @@ func (lease_set LeaseSet) Leases() (leases []Lease, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the Signature data for the LeaseSet, as specified in the Destination's
|
||||||
|
// Key Certificate if present or the 40 bytes following the Leases.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) Signature() (signature Signature, err error) {
|
func (lease_set LeaseSet) Signature() (signature Signature, err error) {
|
||||||
destination, err := lease_set.Destination()
|
destination, err := lease_set.Destination()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -114,7 +247,11 @@ func (lease_set LeaseSet) Signature() (signature Signature, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
start := len(destination) + 256 + 128 + 1 + (44 * lease_count)
|
start := len(destination) +
|
||||||
|
LEASE_SET_PUBKEY_SIZE +
|
||||||
|
LEASE_SET_SPK_SIZE +
|
||||||
|
1 +
|
||||||
|
(LEASE_SIZE * lease_count)
|
||||||
cert, err := destination.Certificate()
|
cert, err := destination.Certificate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
@ -124,20 +261,29 @@ func (lease_set LeaseSet) Signature() (signature Signature, err error) {
|
|||||||
if cert_type == CERT_KEY {
|
if cert_type == CERT_KEY {
|
||||||
end = start + KeyCertificate(cert).SignatureSize()
|
end = start + KeyCertificate(cert).SignatureSize()
|
||||||
} else {
|
} else {
|
||||||
end = start + 40
|
end = start + LEASE_SET_SIG_SIZE
|
||||||
}
|
}
|
||||||
if len(lease_set) < end {
|
lease_set_len := len(lease_set)
|
||||||
err = errors.New("")
|
if lease_set_len < end {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"data_len": lease_set_len,
|
||||||
|
"required_len": end,
|
||||||
|
"reason": "not enough data",
|
||||||
|
}).Error("error parsing signatre")
|
||||||
|
err = errors.New("error parsing signature: not enough data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
copy(signature[:], lease_set[start:end])
|
copy(signature[:], lease_set[start:end])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) Verify() error {
|
func (lease_set LeaseSet) Verify() error {
|
||||||
//data_end := len(destination) +
|
//data_end := len(destination) +
|
||||||
// 256 +
|
// LEASE_SET_PUBKEY_SIZE +
|
||||||
// 128 +
|
// LEASE_SET_SPK_SIZE +
|
||||||
// 1 +
|
// 1 +
|
||||||
// (44 * lease_set.LeaseCount())
|
// (44 * lease_set.LeaseCount())
|
||||||
//data := lease_set[:data_end]
|
//data := lease_set[:data_end]
|
||||||
@ -151,6 +297,9 @@ func (lease_set LeaseSet) Verify() error {
|
|||||||
return nil // verifier.Verify(data, lease_set.Signature())
|
return nil // verifier.Verify(data, lease_set.Signature())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the oldest date from all the Leases in the LeaseSet.
|
||||||
|
//
|
||||||
func (lease_set LeaseSet) OldestExpiration() (date Date, err error) {
|
func (lease_set LeaseSet) OldestExpiration() (date Date, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ROUTER_ADDRESS_MIN_LENGTH = 9
|
ROUTER_ADDRESS_MIN_SIZE = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
type RouterAddress []byte
|
type RouterAddress []byte
|
||||||
@ -51,8 +51,7 @@ type RouterAddress []byte
|
|||||||
// parsing the RouterAddress.
|
// parsing the RouterAddress.
|
||||||
//
|
//
|
||||||
func (router_address RouterAddress) Cost() (cost int, err error) {
|
func (router_address RouterAddress) Cost() (cost int, err error) {
|
||||||
verr, exit := router_address.checkValid()
|
err, exit := router_address.checkValid()
|
||||||
err = verr
|
|
||||||
if exit {
|
if exit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -65,12 +64,11 @@ func (router_address RouterAddress) Cost() (cost int, err error) {
|
|||||||
// parsing the RouterAddress.
|
// parsing the RouterAddress.
|
||||||
//
|
//
|
||||||
func (router_address RouterAddress) Expiration() (date Date, err error) {
|
func (router_address RouterAddress) Expiration() (date Date, err error) {
|
||||||
verr, exit := router_address.checkValid()
|
err, exit := router_address.checkValid()
|
||||||
err = verr
|
|
||||||
if exit {
|
if exit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
copy(date[:], router_address[1:ROUTER_ADDRESS_MIN_LENGTH])
|
copy(date[:], router_address[1:ROUTER_ADDRESS_MIN_SIZE])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,12 +77,11 @@ func (router_address RouterAddress) Expiration() (date Date, err error) {
|
|||||||
// parsing the RouterAddress.
|
// parsing the RouterAddress.
|
||||||
//
|
//
|
||||||
func (router_address RouterAddress) TransportStyle() (str String, err error) {
|
func (router_address RouterAddress) TransportStyle() (str String, err error) {
|
||||||
verr, exit := router_address.checkValid()
|
err, exit := router_address.checkValid()
|
||||||
err = verr
|
|
||||||
if exit {
|
if exit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
str, _, err = ReadString(router_address[ROUTER_ADDRESS_MIN_LENGTH:])
|
str, _, err = ReadString(router_address[ROUTER_ADDRESS_MIN_SIZE:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,12 +90,11 @@ func (router_address RouterAddress) TransportStyle() (str String, err error) {
|
|||||||
// errors encountered parsing the RouterAddress.
|
// errors encountered parsing the RouterAddress.
|
||||||
//
|
//
|
||||||
func (router_address RouterAddress) Options() (mapping Mapping, err error) {
|
func (router_address RouterAddress) Options() (mapping Mapping, err error) {
|
||||||
verr, exit := router_address.checkValid()
|
err, exit := router_address.checkValid()
|
||||||
err = verr
|
|
||||||
if exit {
|
if exit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, remainder, err := ReadString(router_address[ROUTER_ADDRESS_MIN_LENGTH:])
|
_, remainder, err := ReadString(router_address[ROUTER_ADDRESS_MIN_SIZE:])
|
||||||
if len(remainder) == 0 {
|
if len(remainder) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -118,9 +114,9 @@ func (router_address RouterAddress) checkValid() (err error, exit bool) {
|
|||||||
}).Error("invalid router address")
|
}).Error("invalid router address")
|
||||||
err = errors.New("error parsing RouterAddress: no data")
|
err = errors.New("error parsing RouterAddress: no data")
|
||||||
exit = true
|
exit = true
|
||||||
} else if addr_len < ROUTER_ADDRESS_MIN_LENGTH {
|
} else if addr_len < ROUTER_ADDRESS_MIN_SIZE {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"reason": "data too small (len < ROUTER_ADDRESS_MIN_LENGTH)",
|
"reason": "data too small (len < ROUTER_ADDRESS_MIN_SIZE)",
|
||||||
}).Warn("router address format warning")
|
}).Warn("router address format warning")
|
||||||
err = errors.New("warning parsing RouterAddress: data too small")
|
err = errors.New("warning parsing RouterAddress: data too small")
|
||||||
}
|
}
|
||||||
@ -137,8 +133,8 @@ func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []b
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
router_address = append(router_address, data[:ROUTER_ADDRESS_MIN_LENGTH]...)
|
router_address = append(router_address, data[:ROUTER_ADDRESS_MIN_SIZE]...)
|
||||||
str, remainder, err := ReadString(data[ROUTER_ADDRESS_MIN_LENGTH:])
|
str, remainder, err := ReadString(data[ROUTER_ADDRESS_MIN_SIZE:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -150,6 +146,6 @@ func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []b
|
|||||||
mapping = remainder[:map_size+2]
|
mapping = remainder[:map_size+2]
|
||||||
router_address = append(router_address, mapping...)
|
router_address = append(router_address, mapping...)
|
||||||
}
|
}
|
||||||
remainder = data[ROUTER_ADDRESS_MIN_LENGTH+len(str)+len(mapping):]
|
remainder = data[ROUTER_ADDRESS_MIN_SIZE+len(str)+len(mapping):]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,35 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRouterIdentityReadsRouterIdentity(t *testing.T) {
|
func buildFullRouterInfo() RouterInfo {
|
||||||
}
|
// starts with a keys_and_cert
|
||||||
|
router_address_bytes := []byte{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
func TestRouterIdentityWithZeroLenSlice(t *testing.T) {
|
str, _ := ToI2PString("foo")
|
||||||
}
|
mapping, _ := GoMapToMapping(map[string]string{"host": "127.0.0.1", "port": "4567"})
|
||||||
|
router_address_bytes = append(router_address_bytes, []byte(str)...)
|
||||||
func TestRouterIdentityWithInvalidData(t *testing.T) {
|
router_address_bytes = append(router_address_bytes, mapping...)
|
||||||
|
//RouterAddress(router_address_bytes)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPublishedReturnsCorrectDate(t *testing.T) {
|
func TestPublishedReturnsCorrectDate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPublishedWithZeroLenSlice(t *testing.T) {
|
func TestRouterAddressCountReturnsCorrectCount(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPublishedWithInvalidData(t *testing.T) {
|
func TestRouterAdrressesReturnsAddresses(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRouterAdrressesReturnsPartialListWithMissing(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPeerSizeIsZero(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignatureIsCorrectSize(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
STRING_MAX_LENGTH = 256
|
STRING_MAX_SIZE = 256
|
||||||
)
|
)
|
||||||
|
|
||||||
type String []byte
|
type String []byte
|
||||||
@ -79,10 +79,10 @@ func (str String) Data() (data string, err error) {
|
|||||||
//
|
//
|
||||||
func ToI2PString(data string) (str String, err error) {
|
func ToI2PString(data string) (str String, err error) {
|
||||||
data_len := len(data)
|
data_len := len(data)
|
||||||
if data_len >= STRING_MAX_LENGTH {
|
if data_len >= STRING_MAX_SIZE {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"string_len": data_len,
|
"string_len": data_len,
|
||||||
"max_len": STRING_MAX_LENGTH,
|
"max_len": STRING_MAX_SIZE,
|
||||||
"reason": "too much data",
|
"reason": "too much data",
|
||||||
}).Error("cannot create I2P string")
|
}).Error("cannot create I2P string")
|
||||||
err = errors.New("cannot store that much data in I2P string")
|
err = errors.New("cannot store that much data in I2P string")
|
||||||
|
Reference in New Issue
Block a user