mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-08-19 09:45:28 -04:00
Compare commits
22 Commits
0.0.1
...
sntp-exper
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8fa355f067 | ||
![]() |
0c7a3f0f22 | ||
![]() |
3d535f67a1 | ||
![]() |
bba9350506 | ||
![]() |
cbc0de4e7e | ||
![]() |
310ef07d3c | ||
![]() |
14fc6fc3a8 | ||
![]() |
a3ce9d36c6 | ||
![]() |
58a43cdfaf | ||
![]() |
15a5ca5daf | ||
![]() |
08a41686b6 | ||
![]() |
8318fd8f57 | ||
![]() |
9c0552e236 | ||
![]() |
20b018a708 | ||
![]() |
6c62faa49b | ||
![]() |
a7e31b7833 | ||
![]() |
c09161c824 | ||
![]() |
aca62174e6 | ||
![]() |
bd27f00959 | ||
![]() |
05c4d3d973 | ||
![]() |
40d0ea5ff5 | ||
![]() |
58e8f78c56 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,3 +7,5 @@
|
|||||||
go-i2p
|
go-i2p
|
||||||
*.exe
|
*.exe
|
||||||
.idea/
|
.idea/
|
||||||
|
router.info
|
||||||
|
log
|
||||||
|
13
Makefile
13
Makefile
@@ -2,6 +2,7 @@ RELEASE_TAG=0.0.1
|
|||||||
RELEASE_VERSION=${RELEASE_TAG}
|
RELEASE_VERSION=${RELEASE_TAG}
|
||||||
RELEASE_DESCRIPTION=`cat PASTA.md`
|
RELEASE_DESCRIPTION=`cat PASTA.md`
|
||||||
REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
CGO_ENABLED=0
|
||||||
|
|
||||||
ifdef GOROOT
|
ifdef GOROOT
|
||||||
GO = $(GOROOT)/bin/go
|
GO = $(GOROOT)/bin/go
|
||||||
@@ -18,16 +19,16 @@ endif
|
|||||||
build: clean $(EXE)
|
build: clean $(EXE)
|
||||||
|
|
||||||
$(EXE):
|
$(EXE):
|
||||||
$(GO) build -v -o $(EXE)
|
$(GO) build --tags netgo,osusergo -v -o $(EXE)
|
||||||
|
|
||||||
test: fmt
|
test: fmt
|
||||||
$(GO) test -vv -failfast ./lib/common/...
|
$(GO) test -v -failfast ./lib/common/...
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(GO) clean -v
|
$(GO) clean -v
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
find . -name '*.go' -exec gofmt -w -s {} \;
|
find . -name '*.go' -exec gofumpt -w {} \;
|
||||||
|
|
||||||
info:
|
info:
|
||||||
echo "GOROOT: ${GOROOT}"
|
echo "GOROOT: ${GOROOT}"
|
||||||
@@ -36,3 +37,9 @@ info:
|
|||||||
|
|
||||||
release:
|
release:
|
||||||
github-release release -u go-i2p -r go-i2p -n "${RELEASE_VERSION}" -t "${RELEASE_TAG}" -d "${RELEASE_DESCRIPTION}" -p
|
github-release release -u go-i2p -r go-i2p -n "${RELEASE_VERSION}" -t "${RELEASE_TAG}" -d "${RELEASE_DESCRIPTION}" -p
|
||||||
|
|
||||||
|
callvis:
|
||||||
|
go-callvis -format svg -focus upgrade -group pkg,type -limit github.com/go-i2p/go-i2p github.com/go-i2p/go-i2p
|
||||||
|
|
||||||
|
godoc:
|
||||||
|
find lib -type d -exec bash -c "ls {}/*.go && godocdown -o ./{}/doc.md ./{}" \;
|
@@ -41,7 +41,7 @@ please keep up with these changes, as they will not be backward compatible and r
|
|||||||
- [ ] Elligator2
|
- [ ] Elligator2
|
||||||
- [ ] HKDF
|
- [ ] HKDF
|
||||||
- [ ] HMAC
|
- [ ] HMAC
|
||||||
- [ ] Noise subsystem
|
- [/] Noise subsystem
|
||||||
- End-to-End Crypto
|
- End-to-End Crypto
|
||||||
- [ ] Garlic messages
|
- [ ] Garlic messages
|
||||||
- [ ] ElGamal/AES+SessionTag
|
- [ ] ElGamal/AES+SessionTag
|
||||||
@@ -50,7 +50,7 @@ please keep up with these changes, as they will not be backward compatible and r
|
|||||||
- [ ] Message parsing
|
- [ ] Message parsing
|
||||||
- [ ] Message handling
|
- [ ] Message handling
|
||||||
- NetDB
|
- NetDB
|
||||||
- [ ] Local storage
|
- [/] Local storage
|
||||||
- [/] Persistence to disk
|
- [/] Persistence to disk
|
||||||
- [X] Reseeding
|
- [X] Reseeding
|
||||||
- [ ] Lookups
|
- [ ] Lookups
|
||||||
@@ -79,7 +79,7 @@ please keep up with these changes, as they will not be backward compatible and r
|
|||||||
- [ ] Tunnel Message Crypto
|
- [ ] Tunnel Message Crypto
|
||||||
- [ ] Tunnel Message Fragmentation/Reassembly
|
- [ ] Tunnel Message Fragmentation/Reassembly
|
||||||
- Common Data Structures
|
- Common Data Structures
|
||||||
- [/] Keys and Cert
|
- [X] Keys and Cert
|
||||||
- [X] Key Certificates
|
- [X] Key Certificates
|
||||||
- [X] Certificate
|
- [X] Certificate
|
||||||
- [X] Lease
|
- [X] Lease
|
||||||
|
21
go.mod
21
go.mod
@@ -1,11 +1,24 @@
|
|||||||
module github.com/go-i2p/go-i2p
|
module github.com/go-i2p/go-i2p
|
||||||
|
|
||||||
go 1.16
|
go 1.22
|
||||||
|
|
||||||
|
toolchain go1.22.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/emirpasic/gods v1.18.1
|
github.com/beevik/ntp v1.4.3
|
||||||
|
github.com/eyedeekay/go-unzip v0.0.0-20240201194209-560d8225b50e
|
||||||
github.com/flynn/noise v1.1.0
|
github.com/flynn/noise v1.1.0
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.9.0
|
||||||
golang.org/x/crypto v0.23.0
|
go.step.sm/crypto v0.51.2
|
||||||
|
golang.org/x/crypto v0.26.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
golang.org/x/net v0.28.0 // indirect
|
||||||
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
62
go.sum
62
go.sum
@@ -1,8 +1,12 @@
|
|||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
github.com/beevik/ntp v1.4.3 h1:PlbTvE5NNy4QHmA4Mg57n7mcFTmr1W1j3gcK7L1lqho=
|
||||||
|
github.com/beevik/ntp v1.4.3/go.mod h1:Unr8Zg+2dRn7d8bHFuehIMSvvUYssHMxW3Q5Nx4RW5Q=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
github.com/eyedeekay/go-unzip v0.0.0-20240201194209-560d8225b50e h1:NMjWYVkgcQHGOy0/VxU0TU6smrcoxzj9hwDesx2sB0w=
|
||||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
github.com/eyedeekay/go-unzip v0.0.0-20240201194209-560d8225b50e/go.mod h1:fKfFM3BsOOyjtZmEty7FsGzGabXo8Eb/dHjyIhTtxsE=
|
||||||
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
||||||
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
@@ -15,57 +19,27 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
go.step.sm/crypto v0.51.2 h1:5EiCGIMg7IvQTGmJrwRosbXeprtT80OhoS/PJarg60o=
|
||||||
|
go.step.sm/crypto v0.51.2/go.mod h1:QK7czLjN2k+uqVp5CHXxJbhc70kVRSP+0CQF3zsR5M0=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
23
lib/bootstrap/doc.md
Normal file
23
lib/bootstrap/doc.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# bootstrap
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/bootstrap"
|
||||||
|
|
||||||
|
provides generic interfaces for initial bootstrap into network and network
|
||||||
|
### reseeding
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### type Bootstrap
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Bootstrap interface {
|
||||||
|
// get more peers for bootstrap
|
||||||
|
// try obtaining at most n router infos
|
||||||
|
// if n is 0 then try obtaining as many router infos as possible
|
||||||
|
// returns nil and error if we cannot fetch ANY router infos
|
||||||
|
// returns a channel that yields 1 slice of router infos containing n or fewer router infos, caller must close channel after use
|
||||||
|
GetPeers(n int) (chan []router_info.RouterInfo, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
interface defining a way to bootstrap into the i2p network
|
33
lib/common/base32/doc.md
Normal file
33
lib/common/base32/doc.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# base32
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/base32"
|
||||||
|
|
||||||
|
Package base32 implmenets utilities for encoding and decoding text using I2P's
|
||||||
|
### alphabet
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const I2PEncodeAlphabet = "abcdefghijklmnopqrstuvwxyz234567"
|
||||||
|
```
|
||||||
|
I2PEncodeAlphabet is the base32 encoding used throughout I2P. RFC 3548 using
|
||||||
|
lowercase characters.
|
||||||
|
|
||||||
|
```go
|
||||||
|
var I2PEncoding *b32.Encoding = b32.NewEncoding(I2PEncodeAlphabet)
|
||||||
|
```
|
||||||
|
I2PEncoding is the standard base32 encoding used through I2P.
|
||||||
|
|
||||||
|
#### func DecodeString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecodeString(data string) ([]byte, error)
|
||||||
|
```
|
||||||
|
DecodeString decodes base64 string to []byte I2PEncoding
|
||||||
|
|
||||||
|
#### func EncodeToString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeToString(data []byte) string
|
||||||
|
```
|
||||||
|
EncodeToString encodes []byte to a base32 string using I2PEncoding
|
33
lib/common/base64/doc.md
Normal file
33
lib/common/base64/doc.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# base64
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/base64"
|
||||||
|
|
||||||
|
Package base64 implmenets utilities for encoding and decoding text using I2P's
|
||||||
|
### alphabet
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const I2PEncodeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~"
|
||||||
|
```
|
||||||
|
I2PEncodeAlphabet is the base64 encoding used throughout I2P. RFC 4648 with "/""
|
||||||
|
replaced with "~", and "+" replaced with "-".
|
||||||
|
|
||||||
|
```go
|
||||||
|
var I2PEncoding *b64.Encoding = b64.NewEncoding(I2PEncodeAlphabet)
|
||||||
|
```
|
||||||
|
I2PEncoding is the standard base64 encoding used through I2P.
|
||||||
|
|
||||||
|
#### func DecodeString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecodeString(str string) ([]byte, error)
|
||||||
|
```
|
||||||
|
DecodeString decodes base64 string to []byte I2PEncoding
|
||||||
|
|
||||||
|
#### func EncodeToString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncodeToString(data []byte) string
|
||||||
|
```
|
||||||
|
I2PEncoding is the standard base64 encoding used through I2P.
|
@@ -75,7 +75,10 @@ func (c *Certificate) RawBytes() []byte {
|
|||||||
|
|
||||||
// ExcessBytes returns the excess bytes in a certificate found after the specified payload length.
|
// ExcessBytes returns the excess bytes in a certificate found after the specified payload length.
|
||||||
func (c *Certificate) ExcessBytes() []byte {
|
func (c *Certificate) ExcessBytes() []byte {
|
||||||
return c.payload[c.len.Int():]
|
if len(c.payload) >= c.len.Int() {
|
||||||
|
return c.payload[c.len.Int():]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the entire certificate in []byte form, trims payload to specified length.
|
// Bytes returns the entire certificate in []byte form, trims payload to specified length.
|
||||||
@@ -116,8 +119,8 @@ func (c *Certificate) Data() (data []byte) {
|
|||||||
|
|
||||||
// NewCertificate creates a new Certficiate from []byte
|
// NewCertificate creates a new Certficiate from []byte
|
||||||
// returns err if the certificate is too short or if the payload doesn't match specified length.
|
// returns err if the certificate is too short or if the payload doesn't match specified length.
|
||||||
func NewCertificate(data []byte) (certificate *Certificate, err error) {
|
func NewCertificate(data []byte) (certificate Certificate, err error) {
|
||||||
certificate = &Certificate{}
|
certificate = Certificate{}
|
||||||
switch len(data) {
|
switch len(data) {
|
||||||
case 0:
|
case 0:
|
||||||
certificate.kind = Integer([]byte{0})
|
certificate.kind = Integer([]byte{0})
|
||||||
@@ -129,8 +132,8 @@ func NewCertificate(data []byte) (certificate *Certificate, err error) {
|
|||||||
}).Error("invalid certificate, empty")
|
}).Error("invalid certificate, empty")
|
||||||
err = fmt.Errorf("error parsing certificate: certificate is empty")
|
err = fmt.Errorf("error parsing certificate: certificate is empty")
|
||||||
return
|
return
|
||||||
case 1 , 2:
|
case 1, 2:
|
||||||
certificate.kind = Integer(data[0:len(data)-1])
|
certificate.kind = Integer(data[0 : len(data)-1])
|
||||||
certificate.len = Integer([]byte{0})
|
certificate.len = Integer([]byte{0})
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(Certificate) NewCertificate",
|
"at": "(Certificate) NewCertificate",
|
||||||
@@ -163,7 +166,7 @@ func NewCertificate(data []byte) (certificate *Certificate, err error) {
|
|||||||
|
|
||||||
// ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at the end of the input.
|
// ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at the end of the input.
|
||||||
// returns err if the certificate could not be read.
|
// returns err if the certificate could not be read.
|
||||||
func ReadCertificate(data []byte) (certificate *Certificate, remainder []byte, err error) {
|
func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, err error) {
|
||||||
certificate, err = NewCertificate(data)
|
certificate, err = NewCertificate(data)
|
||||||
if err != nil && err.Error() == "certificate parsing warning: certificate data is longer than specified by length" {
|
if err != nil && err.Error() == "certificate parsing warning: certificate data is longer than specified by length" {
|
||||||
err = nil
|
err = nil
|
||||||
|
@@ -32,12 +32,12 @@ func TestCertificateLengthErrWhenTooShort(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
bytes := []byte{0x03, 0x01}
|
bytes := []byte{0x03, 0x01}
|
||||||
certificate, err := NewCertificate(bytes)
|
certificate, _, err := ReadCertificate(bytes)
|
||||||
cert_len := certificate.Length()
|
cert_len := certificate.Length()
|
||||||
|
|
||||||
assert.Equal(cert_len, 0, "certificate.Length() did not return zero length for missing length data")
|
assert.Equal(cert_len, 0, "certificate.Length() did not return zero length for missing length data")
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
assert.Equal("error parsing certificate length: certificate is too short", err.Error(), "correct error message should be returned")
|
assert.Equal("error parsing certificate: certificate is too short", err.Error(), "correct error message should be returned")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,13 +71,10 @@ func TestCertificateDataWhenTooLong(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
bytes := []byte{0x03, 0x00, 0x02, 0xff, 0xff, 0xaa, 0xaa}
|
bytes := []byte{0x03, 0x00, 0x02, 0xff, 0xff, 0xaa, 0xaa}
|
||||||
certificate, err := NewCertificate(bytes)
|
certificate, _, _ := ReadCertificate(bytes)
|
||||||
cert_data := certificate.Data()
|
cert_data := certificate.Data()
|
||||||
|
|
||||||
if assert.NotNil(err) {
|
cert_len := certificate.Length() // len(cert_data)
|
||||||
assert.Equal("certificate parsing warning: certificate data is longer than specified by length", err.Error(), "correct error message should be returned")
|
|
||||||
}
|
|
||||||
cert_len := certificate.Length() //len(cert_data)
|
|
||||||
assert.Equal(cert_len, 2, "certificate.Length() did not return indicated length when data was too long")
|
assert.Equal(cert_len, 2, "certificate.Length() did not return indicated length when data was too long")
|
||||||
if cert_data[0] != 0xff || cert_data[1] != 0xff {
|
if cert_data[0] != 0xff || cert_data[1] != 0xff {
|
||||||
t.Fatal("certificate.Data() returned incorrect data when data was too long")
|
t.Fatal("certificate.Data() returned incorrect data when data was too long")
|
||||||
@@ -144,6 +141,6 @@ func TestReadCertificateWithInvalidLength(t *testing.T) {
|
|||||||
assert.Equal(cert.length(), 2, "ReadCertificate() should populate the certificate with the provided data even when invalid")
|
assert.Equal(cert.length(), 2, "ReadCertificate() should populate the certificate with the provided data even when invalid")
|
||||||
assert.Equal(len(remainder), 0, "ReadCertificate() returned non-zero length remainder on invalid certificate")
|
assert.Equal(len(remainder), 0, "ReadCertificate() returned non-zero length remainder on invalid certificate")
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
assert.Equal("error parsing certificate length: certificate is too short", err.Error(), "correct error message should be returned")
|
assert.Equal("error parsing certificate: certificate is too short", err.Error(), "correct error message should be returned")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
98
lib/common/certificate/doc.md
Normal file
98
lib/common/certificate/doc.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# certificate
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/certificate"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
CERT_NULL = iota
|
||||||
|
CERT_HASHCASH
|
||||||
|
CERT_HIDDEN
|
||||||
|
CERT_SIGNED
|
||||||
|
CERT_MULTIPLE
|
||||||
|
CERT_KEY
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Certificate Types
|
||||||
|
|
||||||
|
```go
|
||||||
|
const CERT_MIN_SIZE = 3
|
||||||
|
```
|
||||||
|
CERT_MIN_SIZE is the minimum size of a valid Certificate in []byte 1 byte for
|
||||||
|
type 2 bytes for payload length
|
||||||
|
|
||||||
|
#### type Certificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Certificate struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Certificate is the representation of an I2P Certificate.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#certificate
|
||||||
|
|
||||||
|
#### func NewCertificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewCertificate(data []byte) (certificate Certificate, err error)
|
||||||
|
```
|
||||||
|
NewCertificate creates a new Certficiate from []byte returns err if the
|
||||||
|
certificate is too short or if the payload doesn't match specified length.
|
||||||
|
|
||||||
|
#### func ReadCertificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at
|
||||||
|
the end of the input. returns err if the certificate could not be read.
|
||||||
|
|
||||||
|
#### func (*Certificate) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *Certificate) Bytes() []byte
|
||||||
|
```
|
||||||
|
Bytes returns the entire certificate in []byte form, trims payload to specified
|
||||||
|
length.
|
||||||
|
|
||||||
|
#### func (*Certificate) Data
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *Certificate) Data() (data []byte)
|
||||||
|
```
|
||||||
|
Data returns the payload of a Certificate, payload is trimmed to the specified
|
||||||
|
length.
|
||||||
|
|
||||||
|
#### func (*Certificate) ExcessBytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *Certificate) ExcessBytes() []byte
|
||||||
|
```
|
||||||
|
ExcessBytes returns the excess bytes in a certificate found after the specified
|
||||||
|
payload length.
|
||||||
|
|
||||||
|
#### func (*Certificate) Length
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *Certificate) Length() (length int)
|
||||||
|
```
|
||||||
|
Length returns the payload length of a Certificate.
|
||||||
|
|
||||||
|
#### func (*Certificate) RawBytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *Certificate) RawBytes() []byte
|
||||||
|
```
|
||||||
|
RawBytes returns the entire certificate in []byte form, includes excess payload
|
||||||
|
data.
|
||||||
|
|
||||||
|
#### func (*Certificate) Type
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *Certificate) Type() (cert_type int)
|
||||||
|
```
|
||||||
|
Type returns the Certificate type specified in the first byte of the
|
||||||
|
Certificate,
|
297
lib/common/data/doc.md
Normal file
297
lib/common/data/doc.md
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
# data
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/data"
|
||||||
|
|
||||||
|
Package data implements common data structures used in higher level structures.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const DATE_SIZE = 8
|
||||||
|
```
|
||||||
|
DATE_SIZE is the length in bytes of an I2P Date.
|
||||||
|
|
||||||
|
```go
|
||||||
|
const MAX_INTEGER_SIZE = 8
|
||||||
|
```
|
||||||
|
MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes.
|
||||||
|
|
||||||
|
```go
|
||||||
|
const STRING_MAX_SIZE = 255
|
||||||
|
```
|
||||||
|
STRING_MAX_SIZE is the maximum number of bytes that can be stored in an I2P
|
||||||
|
string
|
||||||
|
|
||||||
|
#### func PrintErrors
|
||||||
|
|
||||||
|
```go
|
||||||
|
func PrintErrors(errs []error)
|
||||||
|
```
|
||||||
|
PrintErrors prints a formatted list of errors to the console.
|
||||||
|
|
||||||
|
#### func WrapErrors
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WrapErrors(errs []error) error
|
||||||
|
```
|
||||||
|
WrapErrors compiles a slice of errors and returns them wrapped together as a
|
||||||
|
single error.
|
||||||
|
|
||||||
|
#### type Date
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Date [8]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
Date is the represenation of an I2P Date.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#date
|
||||||
|
|
||||||
|
#### func NewDate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewDate(data []byte) (date *Date, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewDate creates a new Date from []byte using ReadDate. Returns a pointer to Date
|
||||||
|
unlike ReadDate.
|
||||||
|
|
||||||
|
#### func ReadDate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadDate(data []byte) (date Date, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadDate creates a Date from []byte using the first DATE_SIZE bytes. Any data
|
||||||
|
after DATE_SIZE is returned as a remainder.
|
||||||
|
|
||||||
|
#### func (Date) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i Date) Bytes() []byte
|
||||||
|
```
|
||||||
|
Bytes returns the raw []byte content of a Date.
|
||||||
|
|
||||||
|
#### func (Date) Int
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i Date) Int() int
|
||||||
|
```
|
||||||
|
Int returns the Date as a Go integer.
|
||||||
|
|
||||||
|
#### func (Date) Time
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (date Date) Time() (date_time time.Time)
|
||||||
|
```
|
||||||
|
Time takes the value stored in date as an 8 byte big-endian integer representing
|
||||||
|
the number of milliseconds since the beginning of unix time and converts it to a
|
||||||
|
Go time.Time struct.
|
||||||
|
|
||||||
|
#### type Hash
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Hash [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
Hash is the represenation of an I2P Hash.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#hash
|
||||||
|
|
||||||
|
#### func HashData
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HashData(data []byte) (h Hash)
|
||||||
|
```
|
||||||
|
HashData returns the SHA256 sum of a []byte input as Hash.
|
||||||
|
|
||||||
|
#### func HashReader
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HashReader(r io.Reader) (h Hash, err error)
|
||||||
|
```
|
||||||
|
HashReader returns the SHA256 sum from all data read from an io.Reader. return
|
||||||
|
error if one occurs while reading from reader
|
||||||
|
|
||||||
|
#### func (Hash) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (h Hash) Bytes() [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type I2PString
|
||||||
|
|
||||||
|
```go
|
||||||
|
type I2PString []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
I2PString is the represenation of an I2P String.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#string
|
||||||
|
|
||||||
|
#### func ReadI2PString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadI2PString returns I2PString from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
||||||
|
|
||||||
|
#### func ToI2PString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ToI2PString(data string) (str I2PString, err error)
|
||||||
|
```
|
||||||
|
ToI2PString converts a Go string to an I2PString. Returns error if the string
|
||||||
|
exceeds STRING_MAX_SIZE.
|
||||||
|
|
||||||
|
#### func (I2PString) Data
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (str I2PString) Data() (data string, err error)
|
||||||
|
```
|
||||||
|
Data returns the I2PString content as a string trimmed to the specified length
|
||||||
|
and not including the length byte. Returns error encountered by Length.
|
||||||
|
|
||||||
|
#### func (I2PString) Length
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (str I2PString) Length() (length int, err error)
|
||||||
|
```
|
||||||
|
Length returns the length specified in the first byte. Returns error if the
|
||||||
|
specified does not match the actual length or the string is otherwise invalid.
|
||||||
|
|
||||||
|
#### type Integer
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Integer []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
Integer is the represenation of an I2P Integer.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#integer
|
||||||
|
|
||||||
|
#### func NewInteger
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewInteger creates a new Integer from []byte using ReadInteger. Limits the
|
||||||
|
length of the created Integer to MAX_INTEGER_SIZE. Returns a pointer to Integer
|
||||||
|
unlike ReadInteger.
|
||||||
|
|
||||||
|
#### func NewIntegerFromInt
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewIntegerFromInt(value int, size int) (integer *Integer, err error)
|
||||||
|
```
|
||||||
|
NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte
|
||||||
|
length.
|
||||||
|
|
||||||
|
#### func ReadInteger
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadInteger(bytes []byte, size int) (Integer, []byte)
|
||||||
|
```
|
||||||
|
ReadInteger returns an Integer from a []byte of specified length. The remaining
|
||||||
|
bytes after the specified length are also returned.
|
||||||
|
|
||||||
|
#### func (Integer) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i Integer) Bytes() []byte
|
||||||
|
```
|
||||||
|
Bytes returns the raw []byte content of an Integer.
|
||||||
|
|
||||||
|
#### func (Integer) Int
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i Integer) Int() int
|
||||||
|
```
|
||||||
|
Int returns the Date as a Go integer
|
||||||
|
|
||||||
|
#### type Mapping
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Mapping struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Mapping is the represenation of an I2P Mapping.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#mapping
|
||||||
|
|
||||||
|
#### func GoMapToMapping
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GoMapToMapping(gomap map[string]string) (mapping *Mapping, err error)
|
||||||
|
```
|
||||||
|
GoMapToMapping converts a Go map of unformatted strings to *Mapping.
|
||||||
|
|
||||||
|
#### func NewMapping
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewMapping(bytes []byte) (values *Mapping, remainder []byte, err []error)
|
||||||
|
```
|
||||||
|
NewMapping creates a new *Mapping from []byte using ReadMapping. Returns a
|
||||||
|
pointer to Mapping unlike ReadMapping.
|
||||||
|
|
||||||
|
#### func ReadMapping
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error)
|
||||||
|
```
|
||||||
|
ReadMapping returns Mapping from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
||||||
|
|
||||||
|
#### func ValuesToMapping
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ValuesToMapping(values MappingValues) *Mapping
|
||||||
|
```
|
||||||
|
ValuesToMapping creates a *Mapping using MappingValues. The values are sorted in
|
||||||
|
the order defined in mappingOrder.
|
||||||
|
|
||||||
|
#### func (*Mapping) Data
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (mapping *Mapping) Data() []byte
|
||||||
|
```
|
||||||
|
Data returns a Mapping in its []byte form.
|
||||||
|
|
||||||
|
#### func (*Mapping) HasDuplicateKeys
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (mapping *Mapping) HasDuplicateKeys() bool
|
||||||
|
```
|
||||||
|
HasDuplicateKeys returns true if two keys in a mapping are identical.
|
||||||
|
|
||||||
|
#### func (Mapping) Values
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (mapping Mapping) Values() MappingValues
|
||||||
|
```
|
||||||
|
Values returns the values contained in a Mapping as MappingValues.
|
||||||
|
|
||||||
|
#### type MappingValues
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MappingValues [][2]I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
MappingValues represents the parsed key value pairs inside of an I2P Mapping.
|
||||||
|
|
||||||
|
#### func ReadMappingValues
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error)
|
||||||
|
```
|
||||||
|
ReadMappingValues returns *MappingValues from a []byte. The remaining bytes
|
||||||
|
after the specified length are also returned. Returns a list of errors that
|
||||||
|
occurred during parsing.
|
||||||
|
|
||||||
|
#### func (MappingValues) Get
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (m MappingValues) Get(key I2PString) I2PString
|
||||||
|
```
|
@@ -23,8 +23,13 @@ Contents
|
|||||||
// https://geti2p.net/spec/common-structures#hash
|
// https://geti2p.net/spec/common-structures#hash
|
||||||
type Hash [32]byte
|
type Hash [32]byte
|
||||||
|
|
||||||
|
func (h Hash) Bytes() [32]byte {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
// HashData returns the SHA256 sum of a []byte input as Hash.
|
// HashData returns the SHA256 sum of a []byte input as Hash.
|
||||||
func HashData(data []byte) (h Hash) {
|
func HashData(data []byte) (h Hash) {
|
||||||
|
// log.Println("Hashing Data:", data)
|
||||||
h = sha256.Sum256(data)
|
h = sha256.Sum256(data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,6 @@ func TestValuesExclusesPairWithBadData(t *testing.T) {
|
|||||||
assert.Equal(key, "a", "Values() returned by data with invalid key contains incorrect present key")
|
assert.Equal(key, "a", "Values() returned by data with invalid key contains incorrect present key")
|
||||||
assert.Equal(val, "b", "Values() returned by data with invalid key contains incorrect present key")
|
assert.Equal(val, "b", "Values() returned by data with invalid key contains incorrect present key")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValuesWarnsMissingData(t *testing.T) {
|
func TestValuesWarnsMissingData(t *testing.T) {
|
||||||
|
@@ -58,9 +58,9 @@ func mappingOrder(values MappingValues) {
|
|||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) {
|
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) {
|
||||||
//mapping := remainder
|
// mapping := remainder
|
||||||
//var remainder = mapping
|
// var remainder = mapping
|
||||||
//var err error
|
// var err error
|
||||||
if remainder == nil || len(remainder) < 1 {
|
if remainder == nil || len(remainder) < 1 {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(Mapping) Values",
|
"at": "(Mapping) Values",
|
||||||
@@ -92,7 +92,7 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
|
|||||||
|
|
||||||
encounteredKeysMap := map[string]bool{}
|
encounteredKeysMap := map[string]bool{}
|
||||||
// pop off length bytes before parsing kv pairs
|
// pop off length bytes before parsing kv pairs
|
||||||
//remainder = remainder[2:]
|
// remainder = remainder[2:]
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Read a key, breaking on fatal errors
|
// Read a key, breaking on fatal errors
|
||||||
@@ -116,12 +116,12 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if stopValueRead(err) {
|
if stopValueRead(err) {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
//return
|
// return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||||
remainder = more
|
remainder = more
|
||||||
//log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
// log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
||||||
|
|
||||||
// Check if key has already been encountered in this mapping
|
// Check if key has already been encountered in this mapping
|
||||||
keyBytes, _ := key_str.Data()
|
keyBytes, _ := key_str.Data()
|
||||||
@@ -160,13 +160,13 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if stopValueRead(err) {
|
if stopValueRead(err) {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
//return
|
// return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||||
remainder = more
|
remainder = more
|
||||||
//log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
// log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
||||||
//log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str)
|
// log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str)
|
||||||
if !beginsWith(remainder, 0x3b) {
|
if !beginsWith(remainder, 0x3b) {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(Mapping) Values",
|
"at": "(Mapping) Values",
|
||||||
@@ -190,5 +190,4 @@ func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingVal
|
|||||||
}
|
}
|
||||||
values = &map_values
|
values = &map_values
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -38,16 +39,20 @@ func (str I2PString) Length() (length int, err error) {
|
|||||||
err = errors.New("error parsing string: zero length")
|
err = errors.New("error parsing string: zero length")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l, _, _ := NewInteger(str, 1)
|
l, _, err := NewInteger(str[:], 1)
|
||||||
|
if err != nil {
|
||||||
|
return l.Int(), err
|
||||||
|
}
|
||||||
length = l.Int()
|
length = l.Int()
|
||||||
str_len := len(str) - 1
|
str_len := len(str)
|
||||||
if length != str_len {
|
if length > str_len {
|
||||||
log.WithFields(log.Fields{
|
/*log.WithFields(log.Fields{
|
||||||
"at": "(I2PString) Length",
|
"at": "(I2PString) Length",
|
||||||
"string_bytes_length": str_len,
|
"string_bytes_length": str_len,
|
||||||
"string_length_field": length,
|
"string_length_field": length,
|
||||||
|
"data": string(str),
|
||||||
"reason": "data less than specified by length",
|
"reason": "data less than specified by length",
|
||||||
}).Error("string format warning")
|
}).Error("string format warning")*/
|
||||||
err = errors.New("string parsing warning: string data is shorter than specified by length")
|
err = errors.New("string parsing warning: string data is shorter than specified by length")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -62,8 +67,11 @@ func (str I2PString) Data() (data string, err error) {
|
|||||||
case "error parsing string: zero length":
|
case "error parsing string: zero length":
|
||||||
return
|
return
|
||||||
case "string parsing warning: string data is shorter than specified by length":
|
case "string parsing warning: string data is shorter than specified by length":
|
||||||
data = string(str[1:])
|
if is, e := ToI2PString(string(str[:])); e != nil {
|
||||||
return
|
return "", e
|
||||||
|
} else {
|
||||||
|
return is.Data()
|
||||||
|
}
|
||||||
case "string parsing warning: string contains data beyond length":
|
case "string parsing warning: string contains data beyond length":
|
||||||
data = string(str[1:])
|
data = string(str[1:])
|
||||||
return
|
return
|
||||||
@@ -109,17 +117,21 @@ func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data_len := length.Int()
|
data_len := length.Int() + 1
|
||||||
str = data[:data_len+1]
|
str = data[:data_len]
|
||||||
remainder = data[data_len+1:]
|
remainder = data[data_len:]
|
||||||
_, err = str.Length()
|
l, err := str.Length()
|
||||||
|
if l != data_len-1 {
|
||||||
|
err = fmt.Errorf("error reading I2P string, length does not match data")
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewI2PString creates a new *I2PString from []byte using ReadI2PString.
|
// NewI2PString creates a new *I2PString from []byte using ReadI2PString.
|
||||||
// Returns a pointer to I2PString unlike ReadI2PString.
|
// Returns a pointer to I2PString unlike ReadI2PString.
|
||||||
func NewI2PString(data []byte) (str *I2PString, remainder []byte, err error) {
|
/*func NewI2PString(data []byte) (str *I2PString, remainder []byte, err error) {
|
||||||
objstr, remainder, err := ReadI2PString(data)
|
objstr, remainder, err := ReadI2PString(data)
|
||||||
str = &objstr
|
str = &objstr
|
||||||
return
|
return
|
||||||
}
|
}*/
|
||||||
|
@@ -26,7 +26,7 @@ Identical to KeysAndCert.
|
|||||||
//
|
//
|
||||||
// https://geti2p.net/spec/common-structures#destination
|
// https://geti2p.net/spec/common-structures#destination
|
||||||
type Destination struct {
|
type Destination struct {
|
||||||
*KeysAndCert
|
KeysAndCert
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base32Address returns the I2P base32 address for this Destination.
|
// Base32Address returns the I2P base32 address for this Destination.
|
||||||
@@ -48,17 +48,9 @@ func (destination Destination) Base64() string {
|
|||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
func ReadDestination(data []byte) (destination Destination, remainder []byte, err error) {
|
func ReadDestination(data []byte) (destination Destination, remainder []byte, err error) {
|
||||||
keys_and_cert, remainder, err := NewKeysAndCert(data)
|
keys_and_cert, remainder, err := ReadKeysAndCert(data)
|
||||||
destination = Destination{
|
destination = Destination{
|
||||||
keys_and_cert,
|
keys_and_cert,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDestination creates a new *Destination from []byte using ReadDestination.
|
|
||||||
// Returns a pointer to Destination unlike ReadDestination.
|
|
||||||
func NewDestination(data []byte) (destination *Destination, remainder []byte, err error) {
|
|
||||||
objdestination, remainder, err := ReadDestination(data)
|
|
||||||
destination = &objdestination
|
|
||||||
return destination, remainder, err
|
|
||||||
}
|
|
||||||
|
42
lib/common/destination/doc.md
Normal file
42
lib/common/destination/doc.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# destination
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/destination"
|
||||||
|
|
||||||
|
Package destination implements the I2P Destination common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### type Destination
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Destination struct {
|
||||||
|
KeysAndCert
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Destination is the represenation of an I2P Destination.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#destination
|
||||||
|
|
||||||
|
#### func ReadDestination
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadDestination(data []byte) (destination Destination, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadDestination returns Destination from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
||||||
|
|
||||||
|
#### func (Destination) Base32Address
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (destination Destination) Base32Address() (str string)
|
||||||
|
```
|
||||||
|
Base32Address returns the I2P base32 address for this Destination.
|
||||||
|
|
||||||
|
#### func (Destination) Base64
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (destination Destination) Base64() string
|
||||||
|
```
|
||||||
|
Base64 returns the I2P base64 address for this Destination.
|
12
lib/common/fuzz/certificate/doc.md
Normal file
12
lib/common/fuzz/certificate/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/fuzz/certificate"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
12
lib/common/fuzz/destination/doc.md
Normal file
12
lib/common/fuzz/destination/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/fuzz/destination"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
12
lib/common/fuzz/keys_and_cert/doc.md
Normal file
12
lib/common/fuzz/keys_and_cert/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/fuzz/keys_and_cert"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
@@ -3,7 +3,7 @@ package exportable
|
|||||||
import common "github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
|
import common "github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
|
||||||
|
|
||||||
func Fuzz(data []byte) int {
|
func Fuzz(data []byte) int {
|
||||||
keys_and_cert, _, _ := common.NewKeysAndCert(data)
|
keys_and_cert, _, _ := common.ReadKeysAndCert(data)
|
||||||
keys_and_cert.Certificate()
|
keys_and_cert.Certificate()
|
||||||
keys_and_cert.PublicKey()
|
keys_and_cert.PublicKey()
|
||||||
keys_and_cert.SigningPublicKey()
|
keys_and_cert.SigningPublicKey()
|
||||||
|
12
lib/common/fuzz/router_address/doc.md
Normal file
12
lib/common/fuzz/router_address/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/fuzz/router_address"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
12
lib/common/fuzz/router_identity/doc.md
Normal file
12
lib/common/fuzz/router_identity/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/fuzz/router_identity"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
12
lib/common/fuzz/string/doc.md
Normal file
12
lib/common/fuzz/string/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/fuzz/string"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
154
lib/common/key_certificate/doc.md
Normal file
154
lib/common/key_certificate/doc.md
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
# key_certificate
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/key_certificate"
|
||||||
|
|
||||||
|
Package key_certificate implements the I2P Destination common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYCERT_SIGN_DSA_SHA1 = iota
|
||||||
|
KEYCERT_SIGN_P256
|
||||||
|
KEYCERT_SIGN_P384
|
||||||
|
KEYCERT_SIGN_P521
|
||||||
|
KEYCERT_SIGN_RSA2048
|
||||||
|
KEYCERT_SIGN_RSA3072
|
||||||
|
KEYCERT_SIGN_RSA4096
|
||||||
|
KEYCERT_SIGN_ED25519
|
||||||
|
KEYCERT_SIGN_ED25519PH
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Key Certificate Signing Key Types
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYCERT_CRYPTO_ELG = iota
|
||||||
|
KEYCERT_CRYPTO_P256
|
||||||
|
KEYCERT_CRYPTO_P384
|
||||||
|
KEYCERT_CRYPTO_P521
|
||||||
|
KEYCERT_CRYPTO_X25519
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Key Certificate Public Key Types
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYCERT_SIGN_DSA_SHA1_SIZE = 128
|
||||||
|
KEYCERT_SIGN_P256_SIZE = 64
|
||||||
|
KEYCERT_SIGN_P384_SIZE = 96
|
||||||
|
KEYCERT_SIGN_P521_SIZE = 132
|
||||||
|
KEYCERT_SIGN_RSA2048_SIZE = 256
|
||||||
|
KEYCERT_SIGN_RSA3072_SIZE = 384
|
||||||
|
KEYCERT_SIGN_RSA4096_SIZE = 512
|
||||||
|
KEYCERT_SIGN_ED25519_SIZE = 32
|
||||||
|
KEYCERT_SIGN_ED25519PH_SIZE = 32
|
||||||
|
)
|
||||||
|
```
|
||||||
|
SigningPublicKey sizes for Signing Key Types
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYCERT_CRYPTO_ELG_SIZE = 256
|
||||||
|
KEYCERT_CRYPTO_P256_SIZE = 64
|
||||||
|
KEYCERT_CRYPTO_P384_SIZE = 96
|
||||||
|
KEYCERT_CRYPTO_P521_SIZE = 132
|
||||||
|
KEYCERT_CRYPTO_X25519_SIZE = 32
|
||||||
|
)
|
||||||
|
```
|
||||||
|
PublicKey sizes for Public Key Types
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYCERT_PUBKEY_SIZE = 256
|
||||||
|
KEYCERT_SPK_SIZE = 128
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Sizes of structures in KeyCertificates
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYCERT_MIN_SIZE = 7
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type KeyCertificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
type KeyCertificate struct {
|
||||||
|
Certificate
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
type KeyCertificate []byte
|
||||||
|
|
||||||
|
#### func KeyCertificateFromCertificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func KeyCertificateFromCertificate(certificate Certificate) *KeyCertificate
|
||||||
|
```
|
||||||
|
KeyCertificateFromCertificate returns a *KeyCertificate from a *Certificate.
|
||||||
|
|
||||||
|
#### func NewKeyCertificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewKeyCertificate creates a new *KeyCertificate from []byte using
|
||||||
|
ReadCertificate. The remaining bytes after the specified length are also
|
||||||
|
returned. Returns a list of errors that occurred during parsing.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) ConstructPublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_key crypto.PublicKey, err error)
|
||||||
|
```
|
||||||
|
ConstructPublicKey returns a PublicKey constructed using any excess data that
|
||||||
|
may be stored in the KeyCertififcate. Returns enr errors encountered while
|
||||||
|
parsing.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) ConstructSigningPublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (signing_public_key crypto.SigningPublicKey, err error)
|
||||||
|
```
|
||||||
|
ConstructSigningPublicKey returns a SingingPublicKey constructed using any
|
||||||
|
excess data that may be stored in the KeyCertificate. Returns any errors
|
||||||
|
encountered while parsing.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) CryptoSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) CryptoSize() (size int)
|
||||||
|
```
|
||||||
|
CryptoSize return the size of a Public Key corresponding to the Key
|
||||||
|
Certificate's PublicKey type.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) Data
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) Data() ([]byte, error)
|
||||||
|
```
|
||||||
|
Data returns the raw []byte contained in the Certificate.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) PublicKeyType
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) PublicKeyType() (pubkey_type int)
|
||||||
|
```
|
||||||
|
PublicKeyType returns the PublicKey type as a Go integer.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) SignatureSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) SignatureSize() (size int)
|
||||||
|
```
|
||||||
|
SignatureSize return the size of a Signature corresponding to the Key
|
||||||
|
Certificate's SigningPublicKey type.
|
||||||
|
|
||||||
|
#### func (KeyCertificate) SigningPublicKeyType
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (key_certificate KeyCertificate) SigningPublicKeyType() (signing_pubkey_type int)
|
||||||
|
```
|
||||||
|
SigningPublicKeyType returns the SigningPublicKey type as a Go integer.
|
@@ -92,7 +92,7 @@ const (
|
|||||||
|
|
||||||
// type KeyCertificate []byte
|
// type KeyCertificate []byte
|
||||||
type KeyCertificate struct {
|
type KeyCertificate struct {
|
||||||
*Certificate
|
Certificate
|
||||||
spkType Integer
|
spkType Integer
|
||||||
cpkType Integer
|
cpkType Integer
|
||||||
}
|
}
|
||||||
@@ -181,11 +181,11 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
|
|||||||
copy(ec_key[KEYCERT_SPK_SIZE:], key_certificate.Certificate.RawBytes()[4:4+extra])
|
copy(ec_key[KEYCERT_SPK_SIZE:], key_certificate.Certificate.RawBytes()[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
|
||||||
//extra := KEYCERT_SIGN_RSA2048_SIZE - 128
|
// extra := KEYCERT_SIGN_RSA2048_SIZE - 128
|
||||||
//copy(rsa_key[:], data)
|
// copy(rsa_key[:], data)
|
||||||
//copy(rsa_key[128:], key_certificate[4:4+extra])
|
// copy(rsa_key[128:], key_certificate[4:4+extra])
|
||||||
//signing_public_key = rsa_key
|
// signing_public_key = rsa_key
|
||||||
case KEYCERT_SIGN_RSA3072:
|
case KEYCERT_SIGN_RSA3072:
|
||||||
case KEYCERT_SIGN_RSA4096:
|
case KEYCERT_SIGN_RSA4096:
|
||||||
case KEYCERT_SIGN_ED25519:
|
case KEYCERT_SIGN_ED25519:
|
||||||
@@ -228,25 +228,29 @@ func (key_certificate KeyCertificate) CryptoSize() (size int) {
|
|||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder []byte, err error) {
|
func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder []byte, err error) {
|
||||||
var certificate *Certificate
|
var certificate Certificate
|
||||||
certificate, remainder, err = ReadCertificate(bytes)
|
certificate, remainder, err = ReadCertificate(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(bytes) < KEYCERT_MIN_SIZE {
|
if len(bytes) < KEYCERT_MIN_SIZE {
|
||||||
err = errors.New("error parsing key certificate: not enough data")
|
err = errors.New("error parsing key certificate: not enough data")
|
||||||
|
remainder = bytes[KEYCERT_MIN_SIZE:]
|
||||||
}
|
}
|
||||||
key_certificate = &KeyCertificate{
|
key_certificate = &KeyCertificate{
|
||||||
Certificate: certificate,
|
Certificate: certificate,
|
||||||
spkType: Integer(bytes[4:5]),
|
|
||||||
cpkType: Integer(bytes[6:7]),
|
|
||||||
}
|
}
|
||||||
remainder = bytes[KEYCERT_MIN_SIZE:]
|
if len(bytes) >= 5 {
|
||||||
|
key_certificate.spkType = Integer(bytes[4:5])
|
||||||
|
}
|
||||||
|
if len(bytes) >= 7 {
|
||||||
|
key_certificate.cpkType = Integer(bytes[6:7])
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyCertificateFromCertificate returns a *KeyCertificate from a *Certificate.
|
// KeyCertificateFromCertificate returns a *KeyCertificate from a *Certificate.
|
||||||
func KeyCertificateFromCertificate(certificate *Certificate) *KeyCertificate {
|
func KeyCertificateFromCertificate(certificate Certificate) *KeyCertificate {
|
||||||
k, _, _ := NewKeyCertificate(certificate.RawBytes())
|
k, _, _ := NewKeyCertificate(certificate.RawBytes())
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
66
lib/common/keys_and_cert/doc.md
Normal file
66
lib/common/keys_and_cert/doc.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# keys_and_cert
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
|
||||||
|
|
||||||
|
Package keys_and_cert implements the I2P KeysAndCert common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
KEYS_AND_CERT_PUBKEY_SIZE = 256
|
||||||
|
KEYS_AND_CERT_SPK_SIZE = 128
|
||||||
|
KEYS_AND_CERT_MIN_SIZE = 387
|
||||||
|
KEYS_AND_CERT_DATA_SIZE = 384
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Sizes of various KeysAndCert structures and requirements
|
||||||
|
|
||||||
|
#### type KeysAndCert
|
||||||
|
|
||||||
|
```go
|
||||||
|
type KeysAndCert struct {
|
||||||
|
KeyCertificate *KeyCertificate
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
KeysAndCert is the represenation of an I2P KeysAndCert.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#keysandcert
|
||||||
|
|
||||||
|
#### func ReadKeysAndCert
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadKeysAndCert creates a new *KeysAndCert from []byte using ReadKeysAndCert.
|
||||||
|
Returns a pointer to KeysAndCert unlike ReadKeysAndCert.
|
||||||
|
|
||||||
|
#### func (KeysAndCert) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (keys_and_cert KeysAndCert) Bytes() []byte
|
||||||
|
```
|
||||||
|
Bytes returns the entire KeyCertificate in []byte form, trims payload to
|
||||||
|
specified length.
|
||||||
|
|
||||||
|
#### func (*KeysAndCert) Certificate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (keys_and_cert *KeysAndCert) Certificate() (cert Certificate)
|
||||||
|
```
|
||||||
|
Certfificate returns the certificate.
|
||||||
|
|
||||||
|
#### func (*KeysAndCert) PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (keys_and_cert *KeysAndCert) PublicKey() (key crypto.PublicKey)
|
||||||
|
```
|
||||||
|
PublicKey returns the public key as a crypto.PublicKey.
|
||||||
|
|
||||||
|
#### func (*KeysAndCert) SigningPublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (keys_and_cert *KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey)
|
||||||
|
```
|
||||||
|
SigningPublicKey returns the signing public key.
|
@@ -79,97 +79,30 @@ type KeysAndCert struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the entire KeyCertificate in []byte form, trims payload to specified length.
|
// Bytes returns the entire KeyCertificate in []byte form, trims payload to specified length.
|
||||||
func (keys_and_cert *KeysAndCert) Bytes() []byte {
|
func (keys_and_cert KeysAndCert) Bytes() []byte {
|
||||||
return keys_and_cert.KeyCertificate.Bytes()
|
return keys_and_cert.KeyCertificate.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKey returns the public key as a crypto.PublicKey.
|
// PublicKey returns the public key as a crypto.PublicKey.
|
||||||
func (keys_and_cert *KeysAndCert) PublicKey() (key crypto.PublicKey) {
|
func (keys_and_cert *KeysAndCert) PublicKey() (key crypto.PublicKey) {
|
||||||
/*cert := keys_and_cert.Certificate()
|
|
||||||
cert_len := cert.Length()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cert_len == 0 {
|
|
||||||
// No Certificate is present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
|
|
||||||
// PublicKey space as ElgPublicKey.
|
|
||||||
var elg_key crypto.ElgPublicKey
|
|
||||||
copy(keys_and_cert[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
|
|
||||||
key = elg_key
|
|
||||||
} else {
|
|
||||||
// A Certificate is present in this KeysAndCert
|
|
||||||
cert_type := cert.Type()
|
|
||||||
if cert_type == CERT_KEY {
|
|
||||||
// This KeysAndCert contains a Key Certificate, construct
|
|
||||||
// a PublicKey from the data in the KeysAndCert and
|
|
||||||
// any additional data in the Certificate.
|
|
||||||
key, err = KeyCertificateFromCertificate(cert).ConstructPublicKey(
|
|
||||||
keys_and_cert[:KEYS_AND_CERT_PUBKEY_SIZE],
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Key Certificate is not present, return the KEYS_AND_CERT_PUBKEY_SIZE byte
|
|
||||||
// PublicKey space as ElgPublicKey. No other Certificate
|
|
||||||
// types are currently in use.
|
|
||||||
var elg_key crypto.ElgPublicKey
|
|
||||||
copy(keys_and_cert[:KEYS_AND_CERT_PUBKEY_SIZE], elg_key[:])
|
|
||||||
key = elg_key
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"at": "(KeysAndCert) PublicKey",
|
|
||||||
"cert_type": cert_type,
|
|
||||||
}).Warn("unused certificate type observed")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return*/
|
|
||||||
return keys_and_cert.publicKey
|
return keys_and_cert.publicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// SigningPublicKey returns the signing public key.
|
// SigningPublicKey returns the signing public key.
|
||||||
func (keys_and_cert *KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey) {
|
func (keys_and_cert *KeysAndCert) SigningPublicKey() (signing_public_key crypto.SigningPublicKey) {
|
||||||
/*cert := keys_and_cert.Certificate()
|
|
||||||
cert_len := cert.Length()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cert_len == 0 {
|
|
||||||
// No Certificate is present, return the KEYS_AND_CERT_SPK_SIZE byte
|
|
||||||
// SigningPublicKey space as legacy DSA SHA1 SigningPublicKey.
|
|
||||||
var dsa_pk crypto.DSAPublicKey
|
|
||||||
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
|
|
||||||
} else {
|
|
||||||
// A Certificate is present in this KeysAndCert
|
|
||||||
cert_type := cert.Type()
|
|
||||||
if cert_type == CERT_KEY {
|
|
||||||
// This KeysAndCert contains a Key Certificate, construct
|
|
||||||
// a SigningPublicKey from the data in the KeysAndCert and
|
|
||||||
// any additional data in the Certificate.
|
|
||||||
signing_public_key, err = KeyCertificateFromCertificate(cert).ConstructSigningPublicKey(
|
|
||||||
keys_and_cert[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_PUBKEY_SIZE+KEYS_AND_CERT_SPK_SIZE],
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Key Certificate is not present, return the KEYS_AND_CERT_SPK_SIZE byte
|
|
||||||
// SigningPublicKey space as legacy SHA DSA1 SigningPublicKey.
|
|
||||||
// No other Certificate types are currently in use.
|
|
||||||
var dsa_pk crypto.DSAPublicKey
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
}*/
|
|
||||||
return keys_and_cert.signingPublicKey
|
return keys_and_cert.signingPublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// Certfificate returns the certificate.
|
// Certfificate returns the certificate.
|
||||||
func (keys_and_cert *KeysAndCert) Certificate() (cert *Certificate) {
|
func (keys_and_cert *KeysAndCert) Certificate() (cert Certificate) {
|
||||||
return keys_and_cert.KeyCertificate.Certificate
|
return keys_and_cert.KeyCertificate.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeysAndCert creates a new *KeysAndCert from []byte using ReadKeysAndCert.
|
// ReadKeysAndCert creates a new *KeysAndCert from []byte using ReadKeysAndCert.
|
||||||
// Returns a pointer to KeysAndCert unlike ReadKeysAndCert.
|
// Returns a pointer to KeysAndCert unlike ReadKeysAndCert.
|
||||||
func NewKeysAndCert(data []byte) (keys_and_cert *KeysAndCert, remainder []byte, err error) {
|
func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) {
|
||||||
data_len := len(data)
|
data_len := len(data)
|
||||||
keys_and_cert = &KeysAndCert{}
|
// keys_and_cert = KeysAndCert{}
|
||||||
if data_len < KEYS_AND_CERT_MIN_SIZE && data_len > KEYS_AND_CERT_DATA_SIZE {
|
if data_len < KEYS_AND_CERT_MIN_SIZE && data_len > KEYS_AND_CERT_DATA_SIZE {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "ReadKeysAndCert",
|
"at": "ReadKeysAndCert",
|
||||||
@@ -192,20 +125,20 @@ func NewKeysAndCert(data []byte) (keys_and_cert *KeysAndCert, remainder []byte,
|
|||||||
}
|
}
|
||||||
keys_and_cert.KeyCertificate, remainder, err = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
|
keys_and_cert.KeyCertificate, remainder, err = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return
|
||||||
}
|
}
|
||||||
// TODO: this only supports one key type right now and it's the old key type, but the layout is the same.
|
// TODO: this only supports one key type right now and it's the old key type, but the layout is the same.
|
||||||
// a case-switch which sets the size of the SPK and the PK should be used to replace the referenced KEYS_AND_CERT_PUBKEY_SIZE
|
// a case-switch which sets the size of the SPK and the PK should be used to replace the referenced KEYS_AND_CERT_PUBKEY_SIZE
|
||||||
// and KEYS_AND_CERT_SPK_SIZE constants in the future.
|
// and KEYS_AND_CERT_SPK_SIZE constants in the future.
|
||||||
keys_and_cert.publicKey, err = keys_and_cert.KeyCertificate.ConstructPublicKey(data[:keys_and_cert.KeyCertificate.CryptoSize()])
|
keys_and_cert.publicKey, err = keys_and_cert.KeyCertificate.ConstructPublicKey(data[:keys_and_cert.KeyCertificate.CryptoSize()])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return
|
||||||
}
|
}
|
||||||
keys_and_cert.signingPublicKey, err = keys_and_cert.KeyCertificate.ConstructSigningPublicKey(data[KEYS_AND_CERT_DATA_SIZE-keys_and_cert.KeyCertificate.SignatureSize() : KEYS_AND_CERT_DATA_SIZE])
|
keys_and_cert.signingPublicKey, err = keys_and_cert.KeyCertificate.ConstructSigningPublicKey(data[KEYS_AND_CERT_DATA_SIZE-keys_and_cert.KeyCertificate.SignatureSize() : KEYS_AND_CERT_DATA_SIZE])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return
|
||||||
}
|
}
|
||||||
padding := data[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_DATA_SIZE-KEYS_AND_CERT_SPK_SIZE]
|
padding := data[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_DATA_SIZE-KEYS_AND_CERT_SPK_SIZE]
|
||||||
keys_and_cert.padding = padding
|
keys_and_cert.padding = padding
|
||||||
return keys_and_cert, remainder, err
|
return
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ func TestCertificateWithValidData(t *testing.T) {
|
|||||||
cert_data := []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}
|
cert_data := []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}
|
||||||
data := make([]byte, 128+256)
|
data := make([]byte, 128+256)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
|
|
||||||
cert := keys_and_cert.Certificate()
|
cert := keys_and_cert.Certificate()
|
||||||
@@ -43,7 +43,7 @@ func TestPublicKeyWithBadData(t *testing.T) {
|
|||||||
data := make([]byte, 128)
|
data := make([]byte, 128)
|
||||||
data = append(data, pub_key_data...)
|
data = append(data, pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
pub_key := keys_and_cert.PublicKey()
|
pub_key := keys_and_cert.PublicKey()
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
@@ -60,7 +60,7 @@ func TestPublicKeyWithBadCertificate(t *testing.T) {
|
|||||||
data := make([]byte, 128)
|
data := make([]byte, 128)
|
||||||
data = append(data, pub_key_data...)
|
data = append(data, pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
pub_key := keys_and_cert.PublicKey()
|
pub_key := keys_and_cert.PublicKey()
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
@@ -77,7 +77,7 @@ func TestPublicKeyWithNullCertificate(t *testing.T) {
|
|||||||
data := make([]byte, 128)
|
data := make([]byte, 128)
|
||||||
data = append(data, pub_key_data...)
|
data = append(data, pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
pub_key := keys_and_cert.PublicKey()
|
pub_key := keys_and_cert.PublicKey()
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
@@ -92,7 +92,7 @@ func TestPublicKeyWithKeyCertificate(t *testing.T) {
|
|||||||
data := make([]byte, 128)
|
data := make([]byte, 128)
|
||||||
data = append(data, pub_key_data...)
|
data = append(data, pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
pub_key := keys_and_cert.PublicKey()
|
pub_key := keys_and_cert.PublicKey()
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
@@ -107,7 +107,7 @@ func TestSigningPublicKeyWithBadData(t *testing.T) {
|
|||||||
data := make([]byte, 93)
|
data := make([]byte, 93)
|
||||||
data = append(data, pub_key_data...)
|
data = append(data, pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
@@ -124,7 +124,7 @@ func TestSigningPublicKeyWithBadCertificate(t *testing.T) {
|
|||||||
data := make([]byte, 128)
|
data := make([]byte, 128)
|
||||||
data = append(data, pub_key_data...)
|
data = append(data, pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
@@ -141,7 +141,7 @@ func TestSigningPublicKeyWithNullCertificate(t *testing.T) {
|
|||||||
signing_pub_key_data := make([]byte, 128)
|
signing_pub_key_data := make([]byte, 128)
|
||||||
data := append(pub_key_data, signing_pub_key_data...)
|
data := append(pub_key_data, signing_pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
@@ -156,7 +156,7 @@ func TestSigningPublicKeyWithKeyCertificate(t *testing.T) {
|
|||||||
signing_pub_key_data := make([]byte, 128)
|
signing_pub_key_data := make([]byte, 128)
|
||||||
data := append(pub_key_data, signing_pub_key_data...)
|
data := append(pub_key_data, signing_pub_key_data...)
|
||||||
data = append(data, cert_data...)
|
data = append(data, cert_data...)
|
||||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||||
|
|
||||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
@@ -167,12 +167,11 @@ func TestNewKeysAndCertWithMissingData(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
cert_data := make([]byte, 128)
|
cert_data := make([]byte, 128)
|
||||||
_, remainder, err := NewKeysAndCert(cert_data)
|
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||||
assert.Equal(0, len(remainder))
|
assert.Equal(0, len(remainder))
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error())
|
assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewKeysAndCertWithMissingCertData(t *testing.T) {
|
func TestNewKeysAndCertWithMissingCertData(t *testing.T) {
|
||||||
@@ -180,7 +179,7 @@ func TestNewKeysAndCertWithMissingCertData(t *testing.T) {
|
|||||||
|
|
||||||
cert_data := make([]byte, 128+256)
|
cert_data := make([]byte, 128+256)
|
||||||
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01}...)
|
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01}...)
|
||||||
_, remainder, err := NewKeysAndCert(cert_data)
|
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||||
assert.Equal(0, len(remainder))
|
assert.Equal(0, len(remainder))
|
||||||
if assert.NotNil(err) {
|
if assert.NotNil(err) {
|
||||||
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error())
|
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error())
|
||||||
@@ -192,7 +191,7 @@ func TestNewKeysAndCertWithValidDataWithCertificate(t *testing.T) {
|
|||||||
|
|
||||||
cert_data := make([]byte, 128+256)
|
cert_data := make([]byte, 128+256)
|
||||||
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}...)
|
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}...)
|
||||||
_, remainder, err := NewKeysAndCert(cert_data)
|
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||||
assert.Equal(0, len(remainder))
|
assert.Equal(0, len(remainder))
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
}
|
}
|
||||||
@@ -202,7 +201,7 @@ func TestNewKeysAndCertWithValidDataWithoutCertificate(t *testing.T) {
|
|||||||
|
|
||||||
cert_data := make([]byte, 128+256)
|
cert_data := make([]byte, 128+256)
|
||||||
cert_data = append(cert_data, []byte{0x00, 0x00, 0x00}...)
|
cert_data = append(cert_data, []byte{0x00, 0x00, 0x00}...)
|
||||||
_, remainder, err := NewKeysAndCert(cert_data)
|
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||||
assert.Equal(0, len(remainder))
|
assert.Equal(0, len(remainder))
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
}
|
}
|
||||||
@@ -212,7 +211,7 @@ func TestNewKeysAndCertWithValidDataWithCertificateAndRemainder(t *testing.T) {
|
|||||||
|
|
||||||
cert_data := make([]byte, 128+256)
|
cert_data := make([]byte, 128+256)
|
||||||
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x41}...)
|
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x41}...)
|
||||||
_, remainder, err := NewKeysAndCert(cert_data)
|
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||||
if assert.Equal(1, len(remainder)) {
|
if assert.Equal(1, len(remainder)) {
|
||||||
assert.Equal("A", string(remainder[0]))
|
assert.Equal("A", string(remainder[0]))
|
||||||
}
|
}
|
||||||
@@ -224,7 +223,7 @@ func TestNewKeysAndCertWithValidDataWithoutCertificateAndRemainder(t *testing.T)
|
|||||||
|
|
||||||
cert_data := make([]byte, 128+256)
|
cert_data := make([]byte, 128+256)
|
||||||
cert_data = append(cert_data, []byte{0x00, 0x00, 0x00, 0x41}...)
|
cert_data = append(cert_data, []byte{0x00, 0x00, 0x00, 0x41}...)
|
||||||
_, remainder, err := NewKeysAndCert(cert_data)
|
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||||
if assert.Equal(1, len(remainder)) {
|
if assert.Equal(1, len(remainder)) {
|
||||||
assert.Equal("A", string(remainder[0]))
|
assert.Equal("A", string(remainder[0]))
|
||||||
}
|
}
|
||||||
|
18
lib/common/keys_and_cert/private_keys_and_cert.go
Normal file
18
lib/common/keys_and_cert/private_keys_and_cert.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package keys_and_cert
|
||||||
|
|
||||||
|
import "crypto"
|
||||||
|
|
||||||
|
// PrivateKeysAndCert contains a KeysAndCert along with the corresponding private keys for the
|
||||||
|
// Public Key and the Signing Public Key
|
||||||
|
type PrivateKeysAndCert struct {
|
||||||
|
KeysAndCert
|
||||||
|
PK_KEY crypto.PrivateKey
|
||||||
|
SPK_KEY crypto.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPrivateKeysAndCert() (*PrivateKeysAndCert, error) {
|
||||||
|
var pkc PrivateKeysAndCert
|
||||||
|
var err error
|
||||||
|
//pkc.PK_KEY, err =
|
||||||
|
return &pkc, err
|
||||||
|
}
|
63
lib/common/lease/doc.md
Normal file
63
lib/common/lease/doc.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# lease
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/lease"
|
||||||
|
|
||||||
|
Package lease implements the I2P lease common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
LEASE_SIZE = 44
|
||||||
|
LEASE_HASH_SIZE = 32
|
||||||
|
LEASE_TUNNEL_ID_SIZE = 4
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Sizes in bytes of various components of a Lease
|
||||||
|
|
||||||
|
#### type Lease
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Lease [LEASE_SIZE]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
Lease is the represenation of an I2P Lease.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#lease
|
||||||
|
|
||||||
|
#### func NewLease
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewLease(data []byte) (lease *Lease, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewLease creates a new *NewLease from []byte using ReadLease. Returns a pointer
|
||||||
|
to KeysAndCert unlike ReadLease.
|
||||||
|
|
||||||
|
#### func ReadLease
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadLease(data []byte) (lease Lease, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadLease returns Lease from a []byte. The remaining bytes after the specified
|
||||||
|
length are also returned. Returns a list of errors that occurred during parsing.
|
||||||
|
|
||||||
|
#### func (Lease) Date
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease Lease) Date() (date Date)
|
||||||
|
```
|
||||||
|
Date returns the date as an I2P Date.
|
||||||
|
|
||||||
|
#### func (Lease) TunnelGateway
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease Lease) TunnelGateway() (hash Hash)
|
||||||
|
```
|
||||||
|
TunnelGateway returns the tunnel gateway as a Hash.
|
||||||
|
|
||||||
|
#### func (Lease) TunnelID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease Lease) TunnelID() uint32
|
||||||
|
```
|
||||||
|
TunnelID returns the tunnel id as a uint23.
|
95
lib/common/lease_set/doc.md
Normal file
95
lib/common/lease_set/doc.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# lease_set
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/lease_set"
|
||||||
|
|
||||||
|
Package lease_set implements the I2P LeastSet common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
LEASE_SET_PUBKEY_SIZE = 256
|
||||||
|
LEASE_SET_SPK_SIZE = 128
|
||||||
|
LEASE_SET_SIG_SIZE = 40
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Sizes of various structures in an I2P LeaseSet
|
||||||
|
|
||||||
|
#### type LeaseSet
|
||||||
|
|
||||||
|
```go
|
||||||
|
type LeaseSet []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
LeaseSet is the represenation of an I2P LeaseSet.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#leaseset
|
||||||
|
|
||||||
|
#### func (LeaseSet) Destination
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) Destination() (destination Destination, err error)
|
||||||
|
```
|
||||||
|
Destination returns the Destination as []byte.
|
||||||
|
|
||||||
|
#### func (LeaseSet) LeaseCount
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) LeaseCount() (count int, err error)
|
||||||
|
```
|
||||||
|
LeaseCount returns the numbert of leases specified by the LeaseCount value as
|
||||||
|
int. returns errors encountered during parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) Leases
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) Leases() (leases []Lease, err error)
|
||||||
|
```
|
||||||
|
Leases returns the leases as []Lease. returns errors encountered during parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) NewestExpiration
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) NewestExpiration() (newest Date, err error)
|
||||||
|
```
|
||||||
|
NewestExpiration returns the newest lease expiration as an I2P Date. Returns
|
||||||
|
errors encountered during parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) OldestExpiration
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) OldestExpiration() (earliest Date, err error)
|
||||||
|
```
|
||||||
|
OldestExpiration returns the oldest lease expiration as an I2P Date. Returns
|
||||||
|
errors encountered during parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error)
|
||||||
|
```
|
||||||
|
PublicKey returns the public key as crypto.ElgPublicKey. Returns errors
|
||||||
|
encountered during parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) Signature
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) Signature() (signature Signature, err error)
|
||||||
|
```
|
||||||
|
Signature returns the signature as Signature. returns errors encountered during
|
||||||
|
parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) SigningKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicKey, err error)
|
||||||
|
```
|
||||||
|
SigningKey returns the signing public key as crypto.SigningPublicKey. returns
|
||||||
|
errors encountered during parsing.
|
||||||
|
|
||||||
|
#### func (LeaseSet) Verify
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (lease_set LeaseSet) Verify() error
|
||||||
|
```
|
||||||
|
Verify returns nil
|
@@ -132,7 +132,7 @@ type LeaseSet struct {
|
|||||||
|
|
||||||
// Destination returns the Destination as []byte.
|
// Destination returns the Destination as []byte.
|
||||||
func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
||||||
keys_and_cert, _, err := NewKeysAndCert(lease_set)
|
keys_and_cert, _, err := ReadKeysAndCert(lease_set)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
|||||||
// PublicKey returns the public key as crypto.ElgPublicKey.
|
// PublicKey returns the public key as crypto.ElgPublicKey.
|
||||||
// Returns errors encountered during parsing.
|
// Returns errors encountered during parsing.
|
||||||
func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error) {
|
func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error) {
|
||||||
_, remainder, err := NewKeysAndCert(lease_set)
|
_, remainder, err := ReadKeysAndCert(lease_set)
|
||||||
remainder_len := len(remainder)
|
remainder_len := len(remainder)
|
||||||
if remainder_len < LEASE_SET_PUBKEY_SIZE {
|
if remainder_len < LEASE_SET_PUBKEY_SIZE {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
@@ -215,7 +215,7 @@ func (lease_set LeaseSet) SigningKey() (signing_public_key crypto.SigningPublicK
|
|||||||
// LeaseCount returns the numbert of leases specified by the LeaseCount value as int.
|
// LeaseCount returns the numbert of leases specified by the LeaseCount value as int.
|
||||||
// returns errors encountered during parsing.
|
// returns errors encountered during parsing.
|
||||||
func (lease_set LeaseSet) LeaseCount() (count int, err error) {
|
func (lease_set LeaseSet) LeaseCount() (count int, err error) {
|
||||||
_, remainder, err := NewKeysAndCert(lease_set)
|
_, remainder, err := ReadKeysAndCert(lease_set)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,9 @@ import (
|
|||||||
func buildDestination() *router_identity.RouterIdentity {
|
func buildDestination() *router_identity.RouterIdentity {
|
||||||
router_ident_data := make([]byte, 128+256)
|
router_ident_data := make([]byte, 128+256)
|
||||||
router_ident_data = append(router_ident_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}...)
|
router_ident_data = append(router_ident_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}...)
|
||||||
ident, _, err := router_identity.NewRouterIdentity(router_ident_data)
|
ident, _, err := router_identity.ReadRouterIdentity(router_ident_data)
|
||||||
panic(err)
|
panic(err)
|
||||||
return ident
|
return &ident
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildPublicKey() []byte {
|
func buildPublicKey() []byte {
|
||||||
@@ -77,7 +77,7 @@ func TestDestinationIsCorrect(t *testing.T) {
|
|||||||
dest, err := lease_set.Destination()
|
dest, err := lease_set.Destination()
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
dest_cert := dest.Certificate()
|
dest_cert := dest.Certificate()
|
||||||
//assert.Nil(err)
|
// assert.Nil(err)
|
||||||
cert_type := dest_cert.Type()
|
cert_type := dest_cert.Type()
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
assert.Equal(certificate.CERT_KEY, cert_type)
|
assert.Equal(certificate.CERT_KEY, cert_type)
|
||||||
|
179
lib/common/router_address/doc.md
Normal file
179
lib/common/router_address/doc.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# router_address
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||||
|
|
||||||
|
Package router_address implements the I2P RouterAddress common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
ROUTER_ADDRESS_MIN_SIZE = 9
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Minimum number of bytes in a valid RouterAddress
|
||||||
|
|
||||||
|
#### type RouterAddress
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RouterAddress struct {
|
||||||
|
TransportCost *Integer
|
||||||
|
ExpirationDate *Date
|
||||||
|
TransportType I2PString
|
||||||
|
TransportOptions *Mapping
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
RouterAddress is the represenation of an I2P RouterAddress.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#routeraddress
|
||||||
|
|
||||||
|
#### func ReadRouterAddress
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadRouterAddress returns RouterAddress from a []byte. The remaining bytes after
|
||||||
|
the specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
||||||
|
|
||||||
|
#### func (RouterAddress) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) Bytes() []byte
|
||||||
|
```
|
||||||
|
Bytes returns the router address as a []byte.
|
||||||
|
|
||||||
|
#### func (RouterAddress) Cost
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) Cost() int
|
||||||
|
```
|
||||||
|
Cost returns the cost for this RouterAddress as a Go integer.
|
||||||
|
|
||||||
|
#### func (RouterAddress) Expiration
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) Expiration() Date
|
||||||
|
```
|
||||||
|
Expiration returns the expiration for this RouterAddress as an I2P Date.
|
||||||
|
|
||||||
|
#### func (RouterAddress) GetOption
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) GetOption(key I2PString) I2PString
|
||||||
|
```
|
||||||
|
GetOption returns the value of the option specified by the key
|
||||||
|
|
||||||
|
#### func (RouterAddress) Host
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) Host() (net.Addr, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) HostString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) HostString() I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) InitializationVector
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) InitializationVector() ([32]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) InitializationVectorString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) InitializationVectorString() I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) IntroducerExpirationString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) IntroducerExpirationString(num int) I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) IntroducerHashString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) IntroducerHashString(num int) I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) IntroducerTagString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) IntroducerTagString(num int) I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*RouterAddress) Network
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address *RouterAddress) Network() string
|
||||||
|
```
|
||||||
|
Network implements net.Addr. It returns the transport type
|
||||||
|
|
||||||
|
#### func (RouterAddress) Options
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) Options() Mapping
|
||||||
|
```
|
||||||
|
Options returns the options for this RouterAddress as an I2P Mapping.
|
||||||
|
|
||||||
|
#### func (RouterAddress) Port
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) Port() (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) PortString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) PortString() I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) ProtocolVersion
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) ProtocolVersion() (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) ProtocolVersionString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) ProtocolVersionString() I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) StaticKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) StaticKey() ([32]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterAddress) StaticKeyString
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) StaticKeyString() I2PString
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*RouterAddress) String
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address *RouterAddress) String() string
|
||||||
|
```
|
||||||
|
String implements net.Addr. It returns the IP address, followed by the options
|
||||||
|
|
||||||
|
#### func (RouterAddress) TransportStyle
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address RouterAddress) TransportStyle() I2PString
|
||||||
|
```
|
||||||
|
TransportStyle returns the transport style for this RouterAddress as an
|
||||||
|
I2PString.
|
||||||
|
|
||||||
|
#### func (*RouterAddress) UDP
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_address *RouterAddress) UDP() bool
|
||||||
|
```
|
@@ -3,6 +3,10 @@ package router_address
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/go-i2p/go-i2p/lib/common/data"
|
. "github.com/go-i2p/go-i2p/lib/common/data"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -63,18 +67,71 @@ options :: Mapping
|
|||||||
//
|
//
|
||||||
// https://geti2p.net/spec/common-structures#routeraddress
|
// https://geti2p.net/spec/common-structures#routeraddress
|
||||||
type RouterAddress struct {
|
type RouterAddress struct {
|
||||||
cost *Integer
|
TransportCost *Integer
|
||||||
expiration *Date
|
ExpirationDate *Date
|
||||||
transport_style *I2PString
|
TransportType I2PString
|
||||||
options *Mapping
|
TransportOptions *Mapping
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network implements net.Addr. It returns the transport type plus 4 or 6
|
||||||
|
func (router_address *RouterAddress) Network() string {
|
||||||
|
if router_address.TransportType == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
str, err := router_address.TransportType.Data()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(str) + router_address.IPVersion()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPVersion returns a string "4" for IPv4 or 6 for IPv6
|
||||||
|
func (router_address *RouterAddress) IPVersion() string {
|
||||||
|
str, err := router_address.CapsString().Data()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(str, "6") {
|
||||||
|
return "6"
|
||||||
|
}
|
||||||
|
return "4"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address *RouterAddress) UDP() bool {
|
||||||
|
return strings.HasPrefix(strings.ToLower(router_address.Network()), "ssu")
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements net.Addr. It returns the IP address, followed by the options
|
||||||
|
func (router_address *RouterAddress) String() string {
|
||||||
|
var rv []string
|
||||||
|
rv = append(rv, string(router_address.TransportStyle()))
|
||||||
|
rv = append(rv, string(router_address.HostString()))
|
||||||
|
rv = append(rv, string(router_address.PortString()))
|
||||||
|
rv = append(rv, string(router_address.StaticKeyString()))
|
||||||
|
rv = append(rv, string(router_address.InitializationVectorString()))
|
||||||
|
rv = append(rv, string(router_address.ProtocolVersionString()))
|
||||||
|
if router_address.UDP() {
|
||||||
|
rv = append(rv, string(router_address.IntroducerHashString(0)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerExpirationString(0)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerTagString(0)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerHashString(1)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerExpirationString(1)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerTagString(1)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerHashString(2)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerExpirationString(2)))
|
||||||
|
rv = append(rv, string(router_address.IntroducerTagString(2)))
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(strings.Join(rv, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
var ex_addr net.Addr = &RouterAddress{}
|
||||||
|
|
||||||
// Bytes returns the router address as a []byte.
|
// Bytes returns the router address as a []byte.
|
||||||
func (router_address RouterAddress) Bytes() []byte {
|
func (router_address RouterAddress) Bytes() []byte {
|
||||||
bytes := make([]byte, 0)
|
bytes := make([]byte, 0)
|
||||||
bytes = append(bytes, router_address.cost.Bytes()...)
|
bytes = append(bytes, router_address.TransportCost.Bytes()...)
|
||||||
bytes = append(bytes, router_address.expiration.Bytes()...)
|
bytes = append(bytes, router_address.ExpirationDate.Bytes()...)
|
||||||
strData, err := router_address.transport_style.Data()
|
strData, err := router_address.TransportType.Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"error": err,
|
"error": err,
|
||||||
@@ -82,28 +139,139 @@ func (router_address RouterAddress) Bytes() []byte {
|
|||||||
} else {
|
} else {
|
||||||
bytes = append(bytes, strData...)
|
bytes = append(bytes, strData...)
|
||||||
}
|
}
|
||||||
bytes = append(bytes, router_address.options.Data()...)
|
bytes = append(bytes, router_address.TransportOptions.Data()...)
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cost returns the cost for this RouterAddress as a Go integer.
|
// Cost returns the cost for this RouterAddress as a Go integer.
|
||||||
func (router_address RouterAddress) Cost() int {
|
func (router_address RouterAddress) Cost() int {
|
||||||
return router_address.cost.Int()
|
return router_address.TransportCost.Int()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expiration returns the expiration for this RouterAddress as an I2P Date.
|
// Expiration returns the expiration for this RouterAddress as an I2P Date.
|
||||||
func (router_address RouterAddress) Expiration() Date {
|
func (router_address RouterAddress) Expiration() Date {
|
||||||
return *router_address.expiration
|
return *router_address.ExpirationDate
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransportStyle returns the transport style for this RouterAddress as an I2PString.
|
// TransportStyle returns the transport style for this RouterAddress as an I2PString.
|
||||||
func (router_address RouterAddress) TransportStyle() I2PString {
|
func (router_address RouterAddress) TransportStyle() I2PString {
|
||||||
return *router_address.transport_style
|
return router_address.TransportType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOption returns the value of the option specified by the key
|
||||||
|
func (router_address RouterAddress) GetOption(key I2PString) I2PString {
|
||||||
|
return router_address.Options().Values().Get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) HostString() I2PString {
|
||||||
|
host, _ := ToI2PString("host")
|
||||||
|
return router_address.GetOption(host)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) PortString() I2PString {
|
||||||
|
port, _ := ToI2PString("port")
|
||||||
|
return router_address.GetOption(port)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) CapsString() I2PString {
|
||||||
|
caps, _ := ToI2PString("caps")
|
||||||
|
return router_address.GetOption(caps)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) StaticKeyString() I2PString {
|
||||||
|
sk, _ := ToI2PString("s")
|
||||||
|
return router_address.GetOption(sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) InitializationVectorString() I2PString {
|
||||||
|
iv, _ := ToI2PString("i")
|
||||||
|
return router_address.GetOption(iv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) ProtocolVersionString() I2PString {
|
||||||
|
v, _ := ToI2PString("v")
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) IntroducerHashString(num int) I2PString {
|
||||||
|
if num >= 0 && num <= 2 {
|
||||||
|
val := strconv.Itoa(num)
|
||||||
|
v, _ := ToI2PString("ih" + val)
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
v, _ := ToI2PString("ih0")
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) IntroducerExpirationString(num int) I2PString {
|
||||||
|
if num >= 0 && num <= 2 {
|
||||||
|
val := strconv.Itoa(num)
|
||||||
|
v, _ := ToI2PString("iexp" + val)
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
v, _ := ToI2PString("iexp0")
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) IntroducerTagString(num int) I2PString {
|
||||||
|
if num >= 0 && num <= 2 {
|
||||||
|
val := strconv.Itoa(num)
|
||||||
|
v, _ := ToI2PString("itag" + val)
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
v, _ := ToI2PString("itag0")
|
||||||
|
return router_address.GetOption(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) Host() (net.Addr, error) {
|
||||||
|
host := router_address.HostString()
|
||||||
|
hostBytes, err := host.Data()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ip := net.ParseIP(hostBytes)
|
||||||
|
if ip == nil {
|
||||||
|
return nil, fmt.Errorf("null host error")
|
||||||
|
}
|
||||||
|
return net.ResolveIPAddr("", ip.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) Port() (string, error) {
|
||||||
|
port := router_address.PortString()
|
||||||
|
portBytes, err := port.Data()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
val, err := strconv.Atoi(portBytes)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strconv.Itoa(val), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) StaticKey() ([32]byte, error) {
|
||||||
|
sk := router_address.StaticKeyString()
|
||||||
|
if len([]byte(sk)) != 32 {
|
||||||
|
return [32]byte{}, fmt.Errorf("error: invalid static key")
|
||||||
|
}
|
||||||
|
return [32]byte(sk), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) InitializationVector() ([32]byte, error) {
|
||||||
|
iv := router_address.InitializationVectorString()
|
||||||
|
if len([]byte(iv)) != 32 {
|
||||||
|
return [32]byte{}, fmt.Errorf("error: invalid static key")
|
||||||
|
}
|
||||||
|
return [32]byte(iv), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (router_address RouterAddress) ProtocolVersion() (string, error) {
|
||||||
|
return router_address.ProtocolVersionString().Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options returns the options for this RouterAddress as an I2P Mapping.
|
// Options returns the options for this RouterAddress as an I2P Mapping.
|
||||||
func (router_address RouterAddress) Options() Mapping {
|
func (router_address RouterAddress) Options() Mapping {
|
||||||
return *router_address.options
|
return *router_address.TransportOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the RouterAddress is empty or if it is too small to contain valid data.
|
// Check if the RouterAddress is empty or if it is too small to contain valid data.
|
||||||
@@ -120,21 +288,21 @@ func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []b
|
|||||||
err = errors.New("error parsing RouterAddress: no data")
|
err = errors.New("error parsing RouterAddress: no data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
router_address.cost, remainder, err = NewInteger(data, 1)
|
router_address.TransportCost, remainder, err = NewInteger(data, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||||
"reason": "error parsing cost",
|
"reason": "error parsing cost",
|
||||||
}).Warn("error parsing RouterAddress")
|
}).Warn("error parsing RouterAddress")
|
||||||
}
|
}
|
||||||
router_address.expiration, remainder, err = NewDate(remainder)
|
router_address.ExpirationDate, remainder, err = NewDate(remainder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||||
"reason": "error parsing expiration",
|
"reason": "error parsing expiration",
|
||||||
}).Error("error parsing RouterAddress")
|
}).Error("error parsing RouterAddress")
|
||||||
}
|
}
|
||||||
router_address.transport_style, remainder, err = NewI2PString(remainder)
|
router_address.TransportType, remainder, err = ReadI2PString(remainder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||||
@@ -142,21 +310,13 @@ func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []b
|
|||||||
}).Error("error parsing RouterAddress")
|
}).Error("error parsing RouterAddress")
|
||||||
}
|
}
|
||||||
var errs []error
|
var errs []error
|
||||||
router_address.options, remainder, errs = NewMapping(remainder)
|
router_address.TransportOptions, remainder, errs = NewMapping(remainder)
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||||
"reason": "error parsing options",
|
"reason": "error parsing options",
|
||||||
"error": err,
|
"error": err,
|
||||||
}).Error("error parsing RouterAddress")
|
}).Error("error parsing RozuterAddress")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouterAddress creates a new *RouterAddress from []byte using ReadRouterAddress.
|
|
||||||
// Returns a pointer to RouterAddress unlike ReadRouterAddress.
|
|
||||||
func NewRouterAddress(data []byte) (router_address *RouterAddress, remainder []byte, err error) {
|
|
||||||
objrouteraddress, remainder, err := ReadRouterAddress(data)
|
|
||||||
router_address = &objrouteraddress
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
@@ -31,7 +31,6 @@ func TestCheckRouterAddressValidReportsDataMissing(t *testing.T) {
|
|||||||
|
|
||||||
err, exit := router_address.checkValid()
|
err, exit := router_address.checkValid()
|
||||||
assert.Equal(exit, false, "checkValid indicates to stop parsing when some fields may be present")
|
assert.Equal(exit, false, "checkValid indicates to stop parsing when some fields may be present")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckRouterAddressValidNoErrWithValidData(t *testing.T) {
|
func TestCheckRouterAddressValidNoErrWithValidData(t *testing.T) {
|
||||||
@@ -40,8 +39,8 @@ func TestCheckRouterAddressValidNoErrWithValidData(t *testing.T) {
|
|||||||
router_address, _, _ := ReadRouterAddress([]byte{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
router_address, _, _ := ReadRouterAddress([]byte{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
||||||
mapping, err := GoMapToMapping(map[string]string{"host": "127.0.0.1", "port": "4567"})
|
mapping, err := GoMapToMapping(map[string]string{"host": "127.0.0.1", "port": "4567"})
|
||||||
assert.Nil(err, "GoMapToMapping() returned error with valid data")
|
assert.Nil(err, "GoMapToMapping() returned error with valid data")
|
||||||
router_address.options = mapping
|
router_address.TransportOptions = mapping
|
||||||
//router_address = append(router_address, mapping...)
|
// router_address = append(router_address, mapping...)
|
||||||
err, exit := router_address.checkValid()
|
err, exit := router_address.checkValid()
|
||||||
|
|
||||||
assert.Nil(err, "checkValid() reported error with valid data")
|
assert.Nil(err, "checkValid() reported error with valid data")
|
||||||
|
28
lib/common/router_identity/doc.md
Normal file
28
lib/common/router_identity/doc.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# router_identity
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/router_identity"
|
||||||
|
|
||||||
|
Package router_identity implements the I2P RouterIdentity common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### type RouterIdentity
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RouterIdentity struct {
|
||||||
|
KeysAndCert
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
RouterIdentity is the represenation of an I2P RouterIdentity.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#routeridentity
|
||||||
|
|
||||||
|
#### func ReadRouterIdentity
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadRouterIdentity(data []byte) (router_identity RouterIdentity, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadRouterIdentity returns RouterIdentity from a []byte. The remaining bytes
|
||||||
|
after the specified length are also returned. Returns a list of errors that
|
||||||
|
occurred during parsing.
|
@@ -20,24 +20,16 @@ Identical to KeysAndCert.
|
|||||||
//
|
//
|
||||||
// https://geti2p.net/spec/common-structures#routeridentity
|
// https://geti2p.net/spec/common-structures#routeridentity
|
||||||
type RouterIdentity struct {
|
type RouterIdentity struct {
|
||||||
*KeysAndCert
|
KeysAndCert
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadRouterIdentity returns RouterIdentity from a []byte.
|
// ReadRouterIdentity returns RouterIdentity from a []byte.
|
||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
func ReadRouterIdentity(data []byte) (router_identity RouterIdentity, remainder []byte, err error) {
|
func ReadRouterIdentity(data []byte) (router_identity RouterIdentity, remainder []byte, err error) {
|
||||||
keys_and_cert, remainder, err := NewKeysAndCert(data)
|
keys_and_cert, remainder, err := ReadKeysAndCert(data)
|
||||||
router_identity = RouterIdentity{
|
router_identity = RouterIdentity{
|
||||||
keys_and_cert,
|
keys_and_cert,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouterIdentity creates a new *RouterIdentity from []byte using ReadRouterIdentity.
|
|
||||||
// Returns a pointer to RouterIdentity unlike ReadRouterIdentity.
|
|
||||||
func NewRouterIdentity(data []byte) (router_identity *RouterIdentity, remainder []byte, err error) {
|
|
||||||
objrouter_identity, remainder, err := ReadRouterIdentity(data)
|
|
||||||
router_identity = &objrouter_identity
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
139
lib/common/router_info/doc.md
Normal file
139
lib/common/router_info/doc.md
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
# router_info
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||||
|
|
||||||
|
Package router_info implements the I2P RouterInfo common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
MIN_GOOD_VERSION = 58
|
||||||
|
MAX_GOOD_VERSION = 99
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
const ROUTER_INFO_MIN_SIZE = 439
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type RouterInfo
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RouterInfo struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
RouterInfo is the represenation of an I2P RouterInfo.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#routerinfo
|
||||||
|
|
||||||
|
#### func ReadRouterInfo
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadRouterInfo returns RouterInfo from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
||||||
|
|
||||||
|
#### func (RouterInfo) Bytes
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info RouterInfo) Bytes() (bytes []byte, err error)
|
||||||
|
```
|
||||||
|
Bytes returns the RouterInfo as a []byte suitable for writing to a stream.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) GoodVersion
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) GoodVersion() bool
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*RouterInfo) IdentHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) IdentHash() Hash
|
||||||
|
```
|
||||||
|
IndentHash returns the identity hash (sha256 sum) for this RouterInfo.
|
||||||
|
|
||||||
|
#### func (RouterInfo) Options
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info RouterInfo) Options() (mapping Mapping)
|
||||||
|
```
|
||||||
|
Options returns the options for this RouterInfo as an I2P Mapping.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) PeerSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) PeerSize() int
|
||||||
|
```
|
||||||
|
PeerSize returns the peer size as a Go integer.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) Published
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) Published() *Date
|
||||||
|
```
|
||||||
|
Published returns the date this RouterInfo was published as an I2P Date.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) Reachable
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) Reachable() bool
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*RouterInfo) RouterAddressCount
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) RouterAddressCount() int
|
||||||
|
```
|
||||||
|
RouterAddressCount returns the count of RouterAddress in this RouterInfo as a Go
|
||||||
|
integer.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) RouterAddresses
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) RouterAddresses() []*RouterAddress
|
||||||
|
```
|
||||||
|
RouterAddresses returns all RouterAddresses for this RouterInfo as
|
||||||
|
[]*RouterAddress.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) RouterCapabilities
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) RouterCapabilities() string
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*RouterInfo) RouterIdentity
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) RouterIdentity() *RouterIdentity
|
||||||
|
```
|
||||||
|
RouterIdentity returns the router identity as *RouterIdentity.
|
||||||
|
|
||||||
|
#### func (*RouterInfo) RouterVersion
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) RouterVersion() string
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (RouterInfo) Signature
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info RouterInfo) Signature() (signature Signature)
|
||||||
|
```
|
||||||
|
Signature returns the signature for this RouterInfo as an I2P Signature.
|
||||||
|
|
||||||
|
#### func (RouterInfo) String
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info RouterInfo) String() string
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*RouterInfo) UnCongested
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (router_info *RouterInfo) UnCongested() bool
|
||||||
|
```
|
@@ -15,8 +15,10 @@ import (
|
|||||||
|
|
||||||
const ROUTER_INFO_MIN_SIZE = 439
|
const ROUTER_INFO_MIN_SIZE = 439
|
||||||
|
|
||||||
const MIN_GOOD_VERSION = 58
|
const (
|
||||||
const MAX_GOOD_VERSION = 99
|
MIN_GOOD_VERSION = 58
|
||||||
|
MAX_GOOD_VERSION = 99
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[RouterInfo]
|
[RouterInfo]
|
||||||
@@ -102,7 +104,7 @@ signature :: Signature
|
|||||||
//
|
//
|
||||||
// https://geti2p.net/spec/common-structures#routerinfo
|
// https://geti2p.net/spec/common-structures#routerinfo
|
||||||
type RouterInfo struct {
|
type RouterInfo struct {
|
||||||
router_identity *RouterIdentity
|
router_identity RouterIdentity
|
||||||
published *Date
|
published *Date
|
||||||
size *Integer
|
size *Integer
|
||||||
addresses []*RouterAddress
|
addresses []*RouterAddress
|
||||||
@@ -112,9 +114,7 @@ type RouterInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the RouterInfo as a []byte suitable for writing to a stream.
|
// Bytes returns the RouterInfo as a []byte suitable for writing to a stream.
|
||||||
func (router_info RouterInfo) Bytes() ([]byte, error) {
|
func (router_info RouterInfo) Bytes() (bytes []byte, err error) {
|
||||||
var err error
|
|
||||||
var bytes []byte
|
|
||||||
bytes = append(bytes, router_info.router_identity.KeysAndCert.Bytes()...)
|
bytes = append(bytes, router_info.router_identity.KeysAndCert.Bytes()...)
|
||||||
bytes = append(bytes, router_info.published.Bytes()...)
|
bytes = append(bytes, router_info.published.Bytes()...)
|
||||||
bytes = append(bytes, router_info.size.Bytes()...)
|
bytes = append(bytes, router_info.size.Bytes()...)
|
||||||
@@ -123,21 +123,33 @@ func (router_info RouterInfo) Bytes() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
bytes = append(bytes, router_info.peer_size.Bytes()...)
|
bytes = append(bytes, router_info.peer_size.Bytes()...)
|
||||||
bytes = append(bytes, router_info.options.Data()...)
|
bytes = append(bytes, router_info.options.Data()...)
|
||||||
//bytes = append(bytes, []byte(*router_info.signature)...)
|
bytes = append(bytes, []byte(*router_info.signature)...)
|
||||||
|
|
||||||
return bytes, err
|
return bytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (router_info RouterInfo) String() string {
|
||||||
|
str := "Certificate: " + string(router_info.router_identity.KeysAndCert.Bytes())
|
||||||
|
str += "Published: " + string(router_info.published.Bytes())
|
||||||
|
str += "Addresses:" + string(router_info.size.Bytes())
|
||||||
|
for index, router_address := range router_info.addresses {
|
||||||
|
str += "Address " + strconv.Itoa(index) + ": " + router_address.String()
|
||||||
|
}
|
||||||
|
str += "Peer Size: " + string(router_info.peer_size.Bytes())
|
||||||
|
str += "Options: " + string(router_info.options.Data())
|
||||||
|
str += "Signature: " + string([]byte(*router_info.signature))
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
// RouterIdentity returns the router identity as *RouterIdentity.
|
// RouterIdentity returns the router identity as *RouterIdentity.
|
||||||
func (router_info *RouterInfo) RouterIdentity() *RouterIdentity {
|
func (router_info *RouterInfo) RouterIdentity() *RouterIdentity {
|
||||||
return router_info.router_identity
|
return &router_info.router_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndentHash returns the identity hash (sha256 sum) for this RouterInfo.
|
// IndentHash returns the identity hash (sha256 sum) for this RouterInfo.
|
||||||
func (router_info *RouterInfo) IdentHash() Hash {
|
func (router_info *RouterInfo) IdentHash() Hash {
|
||||||
ri := router_info.RouterIdentity()
|
data, _ := router_info.RouterIdentity().KeyCertificate.Data()
|
||||||
h := HashData(ri.KeysAndCert.Certificate().Data())
|
return HashData(data)
|
||||||
return h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Published returns the date this RouterInfo was published as an I2P Date.
|
// Published returns the date this RouterInfo was published as an I2P Date.
|
||||||
@@ -167,73 +179,21 @@ func (router_info RouterInfo) Options() (mapping Mapping) {
|
|||||||
return *router_info.options
|
return *router_info.options
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Return the signature of this router info
|
|
||||||
//
|
|
||||||
|
|
||||||
// Signature returns the signature for this RouterInfo as an I2P Signature.
|
// Signature returns the signature for this RouterInfo as an I2P Signature.
|
||||||
func (router_info RouterInfo) Signature() (signature Signature) {
|
func (router_info RouterInfo) Signature() (signature Signature) {
|
||||||
return *router_info.signature
|
return *router_info.signature
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Network implements net.Addr
|
||||||
// Used during parsing to determine where in the RouterInfo the Mapping data begins.
|
func (router_info RouterInfo) Network() string {
|
||||||
//
|
return "i2p"
|
||||||
/*func (router_info RouterInfo) optionsLocation() (location int) {
|
}
|
||||||
data, remainder, err := ReadRouterIdentity(router_info)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
location += len(data)
|
|
||||||
|
|
||||||
remainder_len := len(remainder)
|
|
||||||
if remainder_len < 9 {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"at": "(RouterInfo) optionsLocation",
|
|
||||||
"data_len": remainder_len,
|
|
||||||
"required_len": 9,
|
|
||||||
"reason": "not enough data",
|
|
||||||
}).Error("error parsing router info")
|
|
||||||
err = errors.New("error parsing router addresses: not enough data")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
location += 9
|
|
||||||
|
|
||||||
remaining := remainder[9:]
|
|
||||||
var router_address RouterAddress
|
|
||||||
var router_addresses []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 {
|
|
||||||
location += len(router_address)
|
|
||||||
router_addresses = append(router_addresses, router_address)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
location += 1
|
|
||||||
return
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//
|
|
||||||
// Used during parsing to determine the size of the options in the RouterInfo.
|
|
||||||
//
|
|
||||||
/*func (router_info RouterInfo) optionsSize() (size int) {
|
|
||||||
head := router_info.optionsLocation()
|
|
||||||
s := Integer(router_info[head : head+2])
|
|
||||||
size = s.Int() + 2
|
|
||||||
return
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// ReadRouterInfo returns RouterInfo from a []byte.
|
// ReadRouterInfo returns RouterInfo from a []byte.
|
||||||
// The remaining bytes after the specified length are also returned.
|
// The remaining bytes after the specified length are also returned.
|
||||||
// Returns a list of errors that occurred during parsing.
|
// Returns a list of errors that occurred during parsing.
|
||||||
func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error) {
|
func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error) {
|
||||||
identity, remainder, err := NewRouterIdentity(bytes)
|
info.router_identity, remainder, err = ReadRouterIdentity(bytes)
|
||||||
info.router_identity = identity
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterInfo) ReadRouterInfo",
|
"at": "(RouterInfo) ReadRouterInfo",
|
||||||
@@ -242,9 +202,9 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
|||||||
"reason": "not enough data",
|
"reason": "not enough data",
|
||||||
}).Error("error parsing router info")
|
}).Error("error parsing router info")
|
||||||
err = errors.New("error parsing router info: not enough data")
|
err = errors.New("error parsing router info: not enough data")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
date, remainder, err := NewDate(remainder)
|
info.published, remainder, err = NewDate(remainder)
|
||||||
info.published = date
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterInfo) ReadRouterInfo",
|
"at": "(RouterInfo) ReadRouterInfo",
|
||||||
@@ -254,27 +214,17 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
|||||||
}).Error("error parsing router info")
|
}).Error("error parsing router info")
|
||||||
err = errors.New("error parsing router info: not enough data")
|
err = errors.New("error parsing router info: not enough data")
|
||||||
}
|
}
|
||||||
size, remainder, err := NewInteger(remainder, 1)
|
info.size, remainder, err = NewInteger(remainder, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterInfo) ReadRouterInfo",
|
"at": "(RouterInfo) ReadRouterInfo",
|
||||||
"data_len": len(remainder),
|
"data_len": len(remainder),
|
||||||
"required_len": size.Int(),
|
"required_len": info.size.Int(),
|
||||||
"reason": "read error",
|
"reason": "read error",
|
||||||
}).Error("error parsing router info size")
|
}).Error("error parsing router info size")
|
||||||
}
|
}
|
||||||
info.size = size
|
for i := 0; i < info.size.Int(); i++ {
|
||||||
if err != nil {
|
address, more, err := ReadRouterAddress(remainder)
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"at": "(RouterInfo) ReadRouterInfo",
|
|
||||||
"data_len": len(remainder),
|
|
||||||
"required_len": size.Int(),
|
|
||||||
"reason": "not enough data",
|
|
||||||
}).Error("error parsing router info")
|
|
||||||
err = errors.New("error parsing router info: not enough data")
|
|
||||||
}
|
|
||||||
for i := 0; i < size.Int(); i++ {
|
|
||||||
address, more, err := NewRouterAddress(remainder)
|
|
||||||
remainder = more
|
remainder = more
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
@@ -285,7 +235,7 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
|||||||
}).Error("error parsing router address")
|
}).Error("error parsing router address")
|
||||||
err = errors.New("error parsing router info: not enough data")
|
err = errors.New("error parsing router info: not enough data")
|
||||||
}
|
}
|
||||||
info.addresses = append(info.addresses, address)
|
info.addresses = append(info.addresses, &address)
|
||||||
}
|
}
|
||||||
info.peer_size, remainder, err = NewInteger(remainder, 1)
|
info.peer_size, remainder, err = NewInteger(remainder, 1)
|
||||||
var errs []error
|
var errs []error
|
||||||
@@ -303,6 +253,7 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
|||||||
}
|
}
|
||||||
err = errors.New("error parsing router info: " + estring)
|
err = errors.New("error parsing router info: " + estring)
|
||||||
}
|
}
|
||||||
|
info.signature, remainder, err = NewSignature(remainder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(RouterInfo) ReadRouterInfo",
|
"at": "(RouterInfo) ReadRouterInfo",
|
||||||
@@ -369,11 +320,3 @@ func (router_info *RouterInfo) Reachable() bool {
|
|||||||
}
|
}
|
||||||
return strings.Contains(caps, "R")
|
return strings.Contains(caps, "R")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouterInfo creates a new *RouterInfo from []byte using ReadRouterInfo.
|
|
||||||
// Returns a pointer to RouterInfo unlike ReadRouterInfo.
|
|
||||||
func NewRouterInfo(data []byte) (router_info *RouterInfo, remainder []byte, err error) {
|
|
||||||
routerInfo, remainder, err := ReadRouterInfo(data)
|
|
||||||
router_info = &routerInfo
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
@@ -131,7 +131,6 @@ func TestRouterAddressesReturnsAddresses(t *testing.T) {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) {
|
func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) {
|
||||||
@@ -162,7 +161,6 @@ func TestRouterAddressesReturnsAddressesWithMultiple(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPeerSizeIsZero(t *testing.T) {
|
func TestPeerSizeIsZero(t *testing.T) {
|
||||||
@@ -200,7 +198,7 @@ func TestRouterIdentityIsCorrect(t *testing.T) {
|
|||||||
|
|
||||||
router_info, _ := buildFullRouterInfo()
|
router_info, _ := buildFullRouterInfo()
|
||||||
router_identity := router_info.RouterIdentity()
|
router_identity := router_info.RouterIdentity()
|
||||||
//assert.Nil(err)
|
// assert.Nil(err)
|
||||||
assert.Equal(
|
assert.Equal(
|
||||||
0,
|
0,
|
||||||
bytes.Compare(
|
bytes.Compare(
|
||||||
|
34
lib/common/session_key/doc.md
Normal file
34
lib/common/session_key/doc.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# session_key
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/session_key"
|
||||||
|
|
||||||
|
Package session_key implements the I2P SessionKey common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### type SessionKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SessionKey [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
SessionKey is the represenation of an I2P SessionKey.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#sessionkey
|
||||||
|
|
||||||
|
#### func NewSessionKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewSessionKey(data []byte) (session_key *SessionKey, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewSessionKey creates a new *SessionKey from []byte using ReadSessionKey.
|
||||||
|
Returns a pointer to SessionKey unlike ReadSessionKey.
|
||||||
|
|
||||||
|
#### func ReadSessionKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadSessionKey(bytes []byte) (info SessionKey, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadSessionKey returns SessionKey from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
34
lib/common/session_tag/doc.md
Normal file
34
lib/common/session_tag/doc.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# session_tag
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/session_tag"
|
||||||
|
|
||||||
|
Package session_tag implements the I2P SessionTag common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### type SessionTag
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SessionTag [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
SessionTag is the represenation of an I2P SessionTag.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#session-tag
|
||||||
|
|
||||||
|
#### func NewSessionTag
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewSessionTag(data []byte) (session_tag *SessionTag, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewSessionTag creates a new *SessionTag from []byte using ReadSessionTag.
|
||||||
|
Returns a pointer to SessionTag unlike ReadSessionTag.
|
||||||
|
|
||||||
|
#### func ReadSessionTag
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadSessionTag(bytes []byte) (info SessionTag, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadSessionTag returns SessionTag from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
50
lib/common/signature/doc.md
Normal file
50
lib/common/signature/doc.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# signature
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/common/signature"
|
||||||
|
|
||||||
|
Package signature implements the I2P Signature common data structure
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
DSA_SHA1_SIZE = 40
|
||||||
|
ECDSA_SHA256_P256_SIZE = 64
|
||||||
|
ECDSA_SHA384_P384_SIZE = 96
|
||||||
|
ECDSA_SHA512_P512_SIZE = 132
|
||||||
|
RSA_SHA256_2048_SIZE = 256
|
||||||
|
RSA_SHA384_3072_SIZE = 384
|
||||||
|
RSA_SHA512_4096_SIZE = 512
|
||||||
|
EdDSA_SHA512_Ed25519_SIZE = 64
|
||||||
|
EdDSA_SHA512_Ed25519ph_SIZE = 64
|
||||||
|
RedDSA_SHA512_Ed25519_SIZE = 64
|
||||||
|
)
|
||||||
|
```
|
||||||
|
Lengths of signature keys
|
||||||
|
|
||||||
|
#### type Signature
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Signature []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
Signature is the represenation of an I2P Signature.
|
||||||
|
|
||||||
|
https://geti2p.net/spec/common-structures#signature
|
||||||
|
|
||||||
|
#### func NewSignature
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewSignature(data []byte) (session_tag *Signature, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
NewSignature creates a new *Signature from []byte using ReadSignature. Returns a
|
||||||
|
pointer to Signature unlike ReadSignature.
|
||||||
|
|
||||||
|
#### func ReadSignature
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadSignature(bytes []byte) (info Signature, remainder []byte, err error)
|
||||||
|
```
|
||||||
|
ReadSignature returns Signature from a []byte. The remaining bytes after the
|
||||||
|
specified length are also returned. Returns a list of errors that occurred
|
||||||
|
during parsing.
|
85
lib/config/doc.md
Normal file
85
lib/config/doc.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# config
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/config"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
var DefaultBootstrapConfig = BootstrapConfig{
|
||||||
|
LowPeerThreshold: 10,
|
||||||
|
|
||||||
|
ReseedServers: []*ReseedConfig{},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
default configuration for network bootstrap
|
||||||
|
|
||||||
|
```go
|
||||||
|
var DefaultNetDbConfig = NetDbConfig{
|
||||||
|
Path: filepath.Join(defaultConfig(), "netDb"),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
default settings for netdb
|
||||||
|
|
||||||
|
```go
|
||||||
|
var RouterConfigProperties = DefaultRouterConfig()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type BootstrapConfig
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BootstrapConfig struct {
|
||||||
|
// if we have less than this many peers we should reseed
|
||||||
|
LowPeerThreshold int
|
||||||
|
// reseed servers
|
||||||
|
ReseedServers []*ReseedConfig
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type NetDbConfig
|
||||||
|
|
||||||
|
```go
|
||||||
|
type NetDbConfig struct {
|
||||||
|
// path to network database directory
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
local network database configuration
|
||||||
|
|
||||||
|
#### type ReseedConfig
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ReseedConfig struct {
|
||||||
|
// url of reseed server
|
||||||
|
Url string
|
||||||
|
// fingerprint of reseed su3 signing key
|
||||||
|
SU3Fingerprint string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
configuration for 1 reseed server
|
||||||
|
|
||||||
|
#### type RouterConfig
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RouterConfig struct {
|
||||||
|
// the path to the base config directory where per-system defaults are stored
|
||||||
|
BaseDir string
|
||||||
|
// the path to the working config directory where files are changed
|
||||||
|
WorkingDir string
|
||||||
|
// netdb configuration
|
||||||
|
NetDb *NetDbConfig
|
||||||
|
// configuration for bootstrapping into the network
|
||||||
|
Bootstrap *BootstrapConfig
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
router.config options
|
||||||
|
|
||||||
|
#### func DefaultRouterConfig
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DefaultRouterConfig() *RouterConfig
|
||||||
|
```
|
@@ -12,5 +12,5 @@ type NetDbConfig struct {
|
|||||||
|
|
||||||
// default settings for netdb
|
// default settings for netdb
|
||||||
var DefaultNetDbConfig = NetDbConfig{
|
var DefaultNetDbConfig = NetDbConfig{
|
||||||
Path: filepath.Join(".", "netDb"),
|
Path: filepath.Join(defaultConfig(), "netDb"),
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,48 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
// router.config options
|
// router.config options
|
||||||
type RouterConfig struct {
|
type RouterConfig struct {
|
||||||
|
// the path to the base config directory where per-system defaults are stored
|
||||||
|
BaseDir string
|
||||||
|
// the path to the working config directory where files are changed
|
||||||
|
WorkingDir string
|
||||||
// netdb configuration
|
// netdb configuration
|
||||||
NetDb *NetDbConfig
|
NetDb *NetDbConfig
|
||||||
// configuration for bootstrapping into the network
|
// configuration for bootstrapping into the network
|
||||||
Bootstrap *BootstrapConfig
|
Bootstrap *BootstrapConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaults for router
|
func home() string {
|
||||||
var DefaultRouterConfig = &RouterConfig{
|
h, err := os.UserHomeDir()
|
||||||
NetDb: &DefaultNetDbConfig,
|
if err != nil {
|
||||||
Bootstrap: &DefaultBootstrapConfig,
|
panic(err)
|
||||||
|
}
|
||||||
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func defaultBase() string {
|
||||||
|
return filepath.Join(home(), "go-i2p", "base")
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultConfig() string {
|
||||||
|
return filepath.Join(home(), "go-i2p", "config")
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults for router
|
||||||
|
var defaultRouterConfig = &RouterConfig{
|
||||||
|
NetDb: &DefaultNetDbConfig,
|
||||||
|
Bootstrap: &DefaultBootstrapConfig,
|
||||||
|
BaseDir: defaultBase(),
|
||||||
|
WorkingDir: defaultConfig(),
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultRouterConfig() *RouterConfig {
|
||||||
|
return defaultRouterConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
var RouterConfigProperties = DefaultRouterConfig()
|
||||||
|
141
lib/crypto/curve25519.go
Normal file
141
lib/crypto/curve25519.go
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package crypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
curve25519 "go.step.sm/crypto/x25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Curve25519EncryptTooBig = errors.New("failed to encrypt data, too big for Curve25519")
|
||||||
|
|
||||||
|
type Curve25519PublicKey []byte
|
||||||
|
|
||||||
|
type Curve25519Verifier struct {
|
||||||
|
k []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Curve25519PublicKey) NewVerifier() (v Verifier, err error) {
|
||||||
|
temp := new(Curve25519Verifier)
|
||||||
|
temp.k = k
|
||||||
|
v = temp
|
||||||
|
return temp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Curve25519PublicKey) Len() int {
|
||||||
|
return len(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createCurve25519PublicKey(data []byte) (k *curve25519.PublicKey) {
|
||||||
|
if len(data) == 256 {
|
||||||
|
k2 := curve25519.PublicKey{}
|
||||||
|
copy(k2[:], data)
|
||||||
|
k = &k2
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func createCurve25519Encryption(pub *curve25519.PublicKey, rand io.Reader) (enc *Curve25519Encryption, err error) {
|
||||||
|
/*kbytes := make([]byte, 256)
|
||||||
|
k := new(big.Int)
|
||||||
|
for err == nil {
|
||||||
|
_, err = io.ReadFull(rand, kbytes)
|
||||||
|
k = new(big.Int).SetBytes(kbytes)
|
||||||
|
k = k.Mod(k, pub.P)
|
||||||
|
if k.Sign() != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
enc = &Curve25519Encryption{}
|
||||||
|
}*/
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Curve25519Encryption struct {
|
||||||
|
p, a, b1 *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (curve25519 *Curve25519Encryption) Encrypt(data []byte) (enc []byte, err error) {
|
||||||
|
return curve25519.EncryptPadding(data, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (curve25519 *Curve25519Encryption) EncryptPadding(data []byte, zeroPadding bool) (encrypted []byte, err error) {
|
||||||
|
if len(data) > 222 {
|
||||||
|
err = Curve25519EncryptTooBig
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mbytes := make([]byte, 255)
|
||||||
|
mbytes[0] = 0xFF
|
||||||
|
copy(mbytes[33:], data)
|
||||||
|
// do sha256 of payload
|
||||||
|
d := sha256.Sum256(mbytes[33 : len(data)+33])
|
||||||
|
copy(mbytes[1:], d[:])
|
||||||
|
m := new(big.Int).SetBytes(mbytes)
|
||||||
|
// do encryption
|
||||||
|
b := new(big.Int).Mod(new(big.Int).Mul(curve25519.b1, m), curve25519.p).Bytes()
|
||||||
|
|
||||||
|
if zeroPadding {
|
||||||
|
encrypted = make([]byte, 514)
|
||||||
|
copy(encrypted[1:], curve25519.a.Bytes())
|
||||||
|
copy(encrypted[258:], b)
|
||||||
|
} else {
|
||||||
|
encrypted = make([]byte, 512)
|
||||||
|
copy(encrypted, curve25519.a.Bytes())
|
||||||
|
copy(encrypted[256:], b)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (elg Curve25519PublicKey) NewEncrypter() (enc Encrypter, err error) {
|
||||||
|
k := createCurve25519PublicKey(elg[:])
|
||||||
|
enc, err = createCurve25519Encryption(k, rand.Reader)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Curve25519Verifier) VerifyHash(h, sig []byte) (err error) {
|
||||||
|
if len(sig) != curve25519.SignatureSize {
|
||||||
|
err = ErrBadSignatureSize
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(v.k) != curve25519.PublicKeySize {
|
||||||
|
err = errors.New("failed to verify: invalid curve25519 public key size")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok := curve25519.Verify(v.k, h, sig)
|
||||||
|
if !ok {
|
||||||
|
err = errors.New("failed to verify: invalid signature")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Curve25519Verifier) Verify(data, sig []byte) (err error) {
|
||||||
|
h := sha512.Sum512(data)
|
||||||
|
err = v.VerifyHash(h[:], sig)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Curve25519PrivateKey curve25519.PrivateKey
|
||||||
|
|
||||||
|
type Curve25519Signer struct {
|
||||||
|
k []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Curve25519Signer) Sign(data []byte) (sig []byte, err error) {
|
||||||
|
if len(s.k) != curve25519.PrivateKeySize {
|
||||||
|
err = errors.New("failed to sign: invalid curve25519 private key size")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h := sha512.Sum512(data)
|
||||||
|
sig, err = s.SignHash(h[:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Curve25519Signer) SignHash(h []byte) (sig []byte, err error) {
|
||||||
|
return curve25519.Sign(rand.Reader, s.k, h)
|
||||||
|
}
|
@@ -8,7 +8,6 @@ type Decrypter interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PrivateEncryptionKey interface {
|
type PrivateEncryptionKey interface {
|
||||||
|
|
||||||
// create a new decryption object for this private key to decrypt data encrypted to our public key
|
// create a new decryption object for this private key to decrypt data encrypted to our public key
|
||||||
// returns decrypter or nil and error if the private key is in a bad format
|
// returns decrypter or nil and error if the private key is in a bad format
|
||||||
NewDecrypter() (Decrypter, error)
|
NewDecrypter() (Decrypter, error)
|
||||||
|
623
lib/crypto/doc.md
Normal file
623
lib/crypto/doc.md
Normal file
@@ -0,0 +1,623 @@
|
|||||||
|
# crypto
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/crypto"
|
||||||
|
|
||||||
|
package for i2p specific crpytography
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
IPAD = byte(0x36)
|
||||||
|
OPAD = byte(0x5C)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
var (
|
||||||
|
ElgDecryptFail = errors.New("failed to decrypt elgamal encrypted data")
|
||||||
|
ElgEncryptTooBig = errors.New("failed to encrypt data, too big for elgamal")
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
var (
|
||||||
|
ErrBadSignatureSize = errors.New("bad signature size")
|
||||||
|
ErrInvalidKeyFormat = errors.New("invalid key format")
|
||||||
|
ErrInvalidSignature = errors.New("invalid signature")
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
var Ed25519EncryptTooBig = errors.New("failed to encrypt data, too big for Ed25519")
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
var SHA256 = sha256.Sum256
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ElgamalGenerate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ElgamalGenerate(priv *elgamal.PrivateKey, rand io.Reader) (err error)
|
||||||
|
```
|
||||||
|
generate an elgamal key pair
|
||||||
|
|
||||||
|
#### type DSAPrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DSAPrivateKey [20]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (DSAPrivateKey) Generate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k DSAPrivateKey) Generate() (s DSAPrivateKey, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (DSAPrivateKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k DSAPrivateKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (DSAPrivateKey) NewSigner
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k DSAPrivateKey) NewSigner() (s Signer, err error)
|
||||||
|
```
|
||||||
|
create a new dsa signer
|
||||||
|
|
||||||
|
#### func (DSAPrivateKey) Public
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k DSAPrivateKey) Public() (pk DSAPublicKey, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type DSAPublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DSAPublicKey [128]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (DSAPublicKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k DSAPublicKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (DSAPublicKey) NewVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k DSAPublicKey) NewVerifier() (v Verifier, err error)
|
||||||
|
```
|
||||||
|
create a new dsa verifier
|
||||||
|
|
||||||
|
#### type DSASigner
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DSASigner struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*DSASigner) Sign
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ds *DSASigner) Sign(data []byte) (sig []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*DSASigner) SignHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ds *DSASigner) SignHash(h []byte) (sig []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type DSAVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DSAVerifier struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*DSAVerifier) Verify
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *DSAVerifier) Verify(data, sig []byte) (err error)
|
||||||
|
```
|
||||||
|
verify data with a dsa public key
|
||||||
|
|
||||||
|
#### func (*DSAVerifier) VerifyHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *DSAVerifier) VerifyHash(h, sig []byte) (err error)
|
||||||
|
```
|
||||||
|
verify hash of data with a dsa public key
|
||||||
|
|
||||||
|
#### type Decrypter
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Decrypter interface {
|
||||||
|
// decrypt a block of data
|
||||||
|
// return decrypted block or nil and error if error happens
|
||||||
|
Decrypt(data []byte) ([]byte, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
decrypts data
|
||||||
|
|
||||||
|
#### type ECDSAVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECDSAVerifier struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*ECDSAVerifier) Verify
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *ECDSAVerifier) Verify(data, sig []byte) (err error)
|
||||||
|
```
|
||||||
|
verify a block of data by hashing it and comparing the hash against the
|
||||||
|
signature
|
||||||
|
|
||||||
|
#### func (*ECDSAVerifier) VerifyHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *ECDSAVerifier) VerifyHash(h, sig []byte) (err error)
|
||||||
|
```
|
||||||
|
verify a signature given the hash
|
||||||
|
|
||||||
|
#### type ECP256PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECP256PrivateKey [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type ECP256PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECP256PublicKey [64]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (ECP256PublicKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k ECP256PublicKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (ECP256PublicKey) NewVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k ECP256PublicKey) NewVerifier() (Verifier, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type ECP384PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECP384PrivateKey [48]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type ECP384PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECP384PublicKey [96]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (ECP384PublicKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k ECP384PublicKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (ECP384PublicKey) NewVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k ECP384PublicKey) NewVerifier() (Verifier, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type ECP521PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECP521PrivateKey [66]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type ECP521PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ECP521PublicKey [132]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (ECP521PublicKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k ECP521PublicKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (ECP521PublicKey) NewVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k ECP521PublicKey) NewVerifier() (Verifier, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Ed25519Encryption
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Ed25519Encryption struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*Ed25519Encryption) Encrypt
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ed25519 *Ed25519Encryption) Encrypt(data []byte) (enc []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Ed25519Encryption) EncryptPadding
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ed25519 *Ed25519Encryption) EncryptPadding(data []byte, zeroPadding bool) (encrypted []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Ed25519PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Ed25519PrivateKey ed25519.PrivateKey
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type Ed25519PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Ed25519PublicKey []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (Ed25519PublicKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k Ed25519PublicKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (Ed25519PublicKey) NewEncrypter
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg Ed25519PublicKey) NewEncrypter() (enc Encrypter, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (Ed25519PublicKey) NewVerifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (k Ed25519PublicKey) NewVerifier() (v Verifier, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Ed25519Signer
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Ed25519Signer struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*Ed25519Signer) Sign
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Ed25519Signer) Sign(data []byte) (sig []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Ed25519Signer) SignHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Ed25519Signer) SignHash(h []byte) (sig []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Ed25519Verifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Ed25519Verifier struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*Ed25519Verifier) Verify
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *Ed25519Verifier) Verify(data, sig []byte) (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Ed25519Verifier) VerifyHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *Ed25519Verifier) VerifyHash(h, sig []byte) (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type ElgPrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ElgPrivateKey [256]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (ElgPrivateKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg ElgPrivateKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (ElgPrivateKey) NewDecrypter
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg ElgPrivateKey) NewDecrypter() (dec Decrypter, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type ElgPublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ElgPublicKey [256]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (ElgPublicKey) Len
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg ElgPublicKey) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (ElgPublicKey) NewEncrypter
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg ElgPublicKey) NewEncrypter() (enc Encrypter, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type ElgamalEncryption
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ElgamalEncryption struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*ElgamalEncryption) Encrypt
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg *ElgamalEncryption) Encrypt(data []byte) (enc []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*ElgamalEncryption) EncryptPadding
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (elg *ElgamalEncryption) EncryptPadding(data []byte, zeroPadding bool) (encrypted []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Encrypter
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Encrypter interface {
|
||||||
|
// encrypt a block of data
|
||||||
|
// return encrypted block or nil and error if an error happened
|
||||||
|
Encrypt(data []byte) (enc []byte, err error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
encrypts data
|
||||||
|
|
||||||
|
#### type HMACDigest
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HMACDigest [16]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func I2PHMAC
|
||||||
|
|
||||||
|
```go
|
||||||
|
func I2PHMAC(data []byte, k HMACKey) (d HMACDigest)
|
||||||
|
```
|
||||||
|
do i2p hmac
|
||||||
|
|
||||||
|
#### type HMACKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HMACKey [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type PrivateEncryptionKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type PrivateEncryptionKey interface {
|
||||||
|
// create a new decryption object for this private key to decrypt data encrypted to our public key
|
||||||
|
// returns decrypter or nil and error if the private key is in a bad format
|
||||||
|
NewDecrypter() (Decrypter, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type PublicEncryptionKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type PublicEncryptionKey interface {
|
||||||
|
// create a new encrypter to encrypt data to this public key
|
||||||
|
NewEncrypter() (Encrypter, error)
|
||||||
|
|
||||||
|
// length of this public key in bytes
|
||||||
|
Len() int
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type PublicKey interface {
|
||||||
|
Len() int
|
||||||
|
NewEncrypter() (Encrypter, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type RSA2048PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RSA2048PrivateKey [512]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type RSA2048PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RSA2048PublicKey [256]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type RSA3072PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RSA3072PrivateKey [786]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type RSA3072PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RSA3072PublicKey [384]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type RSA4096PrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RSA4096PrivateKey [1024]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type RSA4096PublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RSA4096PublicKey [512]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type Signer
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Signer interface {
|
||||||
|
// sign data with our private key by calling SignHash after hashing the data we are given
|
||||||
|
// return signature or nil signature and error if an error happened
|
||||||
|
Sign(data []byte) (sig []byte, err error)
|
||||||
|
|
||||||
|
// sign hash of data with our private key
|
||||||
|
// return signature or nil signature and error if an error happened
|
||||||
|
SignHash(h []byte) (sig []byte, err error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
type for signing data
|
||||||
|
|
||||||
|
#### type SigningPrivateKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SigningPrivateKey interface {
|
||||||
|
// create a new signer to sign data
|
||||||
|
// return signer or nil and error if key format is invalid
|
||||||
|
NewSigner() (Signer, error)
|
||||||
|
// length of this private key
|
||||||
|
Len() int
|
||||||
|
// get public key or return nil and error if invalid key data in private key
|
||||||
|
Public() (SigningPublicKey, error)
|
||||||
|
// generate a new private key, put it into itself
|
||||||
|
// returns itself or nil and error if an error occurs
|
||||||
|
Generate() (SigningPrivateKey, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
key for signing data
|
||||||
|
|
||||||
|
#### type SigningPublicKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SigningPublicKey interface {
|
||||||
|
// create new Verifier to verify the validity of signatures
|
||||||
|
// return verifier or nil and error if key format is invalid
|
||||||
|
NewVerifier() (Verifier, error)
|
||||||
|
// get the size of this public key
|
||||||
|
Len() int
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
key for verifying data
|
||||||
|
|
||||||
|
#### type Tunnel
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Tunnel struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func NewTunnelCrypto
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Tunnel) Decrypt
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (t *Tunnel) Decrypt(td *TunnelData)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Tunnel) Encrypt
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (t *Tunnel) Encrypt(td *TunnelData)
|
||||||
|
```
|
||||||
|
encrypt tunnel data in place
|
||||||
|
|
||||||
|
#### type TunnelData
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelData [1028]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type TunnelIV
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelIV []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
The initialization vector for a tunnel message
|
||||||
|
|
||||||
|
#### type TunnelKey
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelKey [32]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
A symetric key for encrypting tunnel messages
|
||||||
|
|
||||||
|
#### type Verifier
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Verifier interface {
|
||||||
|
// verify hashed data with this signing key
|
||||||
|
// return nil on valid signature otherwise error
|
||||||
|
VerifyHash(h, sig []byte) error
|
||||||
|
// verify an unhashed piece of data by hashing it and calling VerifyHash
|
||||||
|
Verify(data, sig []byte) error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
type for verifying signatures
|
@@ -2,9 +2,10 @@ package crypto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDSA(t *testing.T) {
|
func TestDSA(t *testing.T) {
|
||||||
|
@@ -44,8 +44,10 @@ func createECVerifier(c elliptic.Curve, h crypto.Hash, k []byte) (ev *ECDSAVerif
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type ECP256PublicKey [64]byte
|
type (
|
||||||
type ECP256PrivateKey [32]byte
|
ECP256PublicKey [64]byte
|
||||||
|
ECP256PrivateKey [32]byte
|
||||||
|
)
|
||||||
|
|
||||||
func (k ECP256PublicKey) Len() int {
|
func (k ECP256PublicKey) Len() int {
|
||||||
return len(k)
|
return len(k)
|
||||||
@@ -55,8 +57,10 @@ func (k ECP256PublicKey) NewVerifier() (Verifier, error) {
|
|||||||
return createECVerifier(elliptic.P256(), crypto.SHA256, k[:])
|
return createECVerifier(elliptic.P256(), crypto.SHA256, k[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
type ECP384PublicKey [96]byte
|
type (
|
||||||
type ECP384PrivateKey [48]byte
|
ECP384PublicKey [96]byte
|
||||||
|
ECP384PrivateKey [48]byte
|
||||||
|
)
|
||||||
|
|
||||||
func (k ECP384PublicKey) Len() int {
|
func (k ECP384PublicKey) Len() int {
|
||||||
return len(k)
|
return len(k)
|
||||||
@@ -66,8 +70,10 @@ func (k ECP384PublicKey) NewVerifier() (Verifier, error) {
|
|||||||
return createECVerifier(elliptic.P384(), crypto.SHA384, k[:])
|
return createECVerifier(elliptic.P384(), crypto.SHA384, k[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
type ECP521PublicKey [132]byte
|
type (
|
||||||
type ECP521PrivateKey [66]byte
|
ECP521PublicKey [132]byte
|
||||||
|
ECP521PrivateKey [66]byte
|
||||||
|
)
|
||||||
|
|
||||||
func (k ECP521PublicKey) Len() int {
|
func (k ECP521PublicKey) Len() int {
|
||||||
return len(k)
|
return len(k)
|
||||||
|
@@ -30,11 +30,15 @@ var elgp = new(big.Int).SetBytes([]byte{
|
|||||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
})
|
})
|
||||||
|
|
||||||
var one = big.NewInt(1)
|
var (
|
||||||
var elgg = big.NewInt(2)
|
one = big.NewInt(1)
|
||||||
|
elgg = big.NewInt(2)
|
||||||
|
)
|
||||||
|
|
||||||
var ElgDecryptFail = errors.New("failed to decrypt elgamal encrypted data")
|
var (
|
||||||
var ElgEncryptTooBig = errors.New("failed to encrypt data, too big for elgamal")
|
ElgDecryptFail = errors.New("failed to decrypt elgamal encrypted data")
|
||||||
|
ElgEncryptTooBig = errors.New("failed to encrypt data, too big for elgamal")
|
||||||
|
)
|
||||||
|
|
||||||
// generate an elgamal key pair
|
// generate an elgamal key pair
|
||||||
func ElgamalGenerate(priv *elgamal.PrivateKey, rand io.Reader) (err error) {
|
func ElgamalGenerate(priv *elgamal.PrivateKey, rand io.Reader) (err error) {
|
||||||
@@ -184,8 +188,10 @@ func createElgamalEncryption(pub *elgamal.PublicKey, rand io.Reader) (enc *Elgam
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type ElgPublicKey [256]byte
|
type (
|
||||||
type ElgPrivateKey [256]byte
|
ElgPublicKey [256]byte
|
||||||
|
ElgPrivateKey [256]byte
|
||||||
|
)
|
||||||
|
|
||||||
func (elg ElgPublicKey) Len() int {
|
func (elg ElgPublicKey) Len() int {
|
||||||
return len(elg)
|
return len(elg)
|
||||||
|
@@ -3,10 +3,11 @@ package crypto
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"golang.org/x/crypto/openpgp/elgamal"
|
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/crypto/openpgp/elgamal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkElgGenerate(b *testing.B) {
|
func BenchmarkElgGenerate(b *testing.B) {
|
||||||
@@ -46,7 +47,6 @@ func BenchmarkElgDecrypt(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Infof("%d fails %d rounds", fails, b.N)
|
log.Infof("%d fails %d rounds", fails, b.N)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkElgEncrypt(b *testing.B) {
|
func BenchmarkElgEncrypt(b *testing.B) {
|
||||||
|
@@ -8,7 +8,6 @@ type Encrypter interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PublicEncryptionKey interface {
|
type PublicEncryptionKey interface {
|
||||||
|
|
||||||
// create a new encrypter to encrypt data to this public key
|
// create a new encrypter to encrypt data to this public key
|
||||||
NewEncrypter() (Encrypter, error)
|
NewEncrypter() (Encrypter, error)
|
||||||
|
|
||||||
|
@@ -4,11 +4,15 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
)
|
)
|
||||||
|
|
||||||
const IPAD = byte(0x36)
|
const (
|
||||||
const OPAD = byte(0x5C)
|
IPAD = byte(0x36)
|
||||||
|
OPAD = byte(0x5C)
|
||||||
|
)
|
||||||
|
|
||||||
type HMACKey [32]byte
|
type (
|
||||||
type HMACDigest [16]byte
|
HMACKey [32]byte
|
||||||
|
HMACDigest [16]byte
|
||||||
|
)
|
||||||
|
|
||||||
func (hk HMACKey) xor(p byte) (i []byte) {
|
func (hk HMACKey) xor(p byte) (i []byte) {
|
||||||
i = make([]byte, 64)
|
i = make([]byte, 64)
|
||||||
@@ -25,7 +29,6 @@ func (hk HMACKey) xor(p byte) (i []byte) {
|
|||||||
|
|
||||||
// do i2p hmac
|
// do i2p hmac
|
||||||
func I2PHMAC(data []byte, k HMACKey) (d HMACDigest) {
|
func I2PHMAC(data []byte, k HMACKey) (d HMACDigest) {
|
||||||
|
|
||||||
buff := make([]byte, 64+len(data))
|
buff := make([]byte, 64+len(data))
|
||||||
ip := k.xor(IPAD)
|
ip := k.xor(IPAD)
|
||||||
copy(buff, ip)
|
copy(buff, ip)
|
||||||
|
@@ -1,10 +1,16 @@
|
|||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
type RSA2048PublicKey [256]byte
|
type (
|
||||||
type RSA2048PrivateKey [512]byte
|
RSA2048PublicKey [256]byte
|
||||||
|
RSA2048PrivateKey [512]byte
|
||||||
|
)
|
||||||
|
|
||||||
type RSA3072PublicKey [384]byte
|
type (
|
||||||
type RSA3072PrivateKey [786]byte
|
RSA3072PublicKey [384]byte
|
||||||
|
RSA3072PrivateKey [786]byte
|
||||||
|
)
|
||||||
|
|
||||||
type RSA4096PublicKey [512]byte
|
type (
|
||||||
type RSA4096PrivateKey [1024]byte
|
RSA4096PublicKey [512]byte
|
||||||
|
RSA4096PrivateKey [1024]byte
|
||||||
|
)
|
||||||
|
@@ -4,9 +4,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrBadSignatureSize = errors.New("bad signature size")
|
var (
|
||||||
var ErrInvalidKeyFormat = errors.New("invalid key format")
|
ErrBadSignatureSize = errors.New("bad signature size")
|
||||||
var ErrInvalidSignature = errors.New("invalid signature")
|
ErrInvalidKeyFormat = errors.New("invalid key format")
|
||||||
|
ErrInvalidSignature = errors.New("invalid signature")
|
||||||
|
)
|
||||||
|
|
||||||
// type for verifying signatures
|
// type for verifying signatures
|
||||||
type Verifier interface {
|
type Verifier interface {
|
||||||
|
@@ -19,7 +19,6 @@ type Tunnel struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error) {
|
func NewTunnelCrypto(layerKey, ivKey TunnelKey) (t *Tunnel, err error) {
|
||||||
|
|
||||||
t = new(Tunnel)
|
t = new(Tunnel)
|
||||||
t.layerKey, err = aes.NewCipher(layerKey[:])
|
t.layerKey, err = aes.NewCipher(layerKey[:])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@@ -149,8 +149,10 @@ padding :: Data
|
|||||||
total length: 222
|
total length: 222
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type BuildRequestRecordElGamalAES [528]byte
|
type (
|
||||||
type BuildRequestRecordElGamal [528]byte
|
BuildRequestRecordElGamalAES [528]byte
|
||||||
|
BuildRequestRecordElGamal [528]byte
|
||||||
|
)
|
||||||
|
|
||||||
type BuildRequestRecord struct {
|
type BuildRequestRecord struct {
|
||||||
ReceiveTunnel tunnel.TunnelID
|
ReceiveTunnel tunnel.TunnelID
|
||||||
|
@@ -14,7 +14,6 @@ func TestReadBuildRequestRecordReceiveTunnelTooLittleData(t *testing.T) {
|
|||||||
receive_tunnel, err := readBuildRequestRecordReceiveTunnel([]byte{0x01})
|
receive_tunnel, err := readBuildRequestRecordReceiveTunnel([]byte{0x01})
|
||||||
assert.Equal(tunnel.TunnelID(0), receive_tunnel)
|
assert.Equal(tunnel.TunnelID(0), receive_tunnel)
|
||||||
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
|
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadBuildRequestRecordReceiveTunnelValidData(t *testing.T) {
|
func TestReadBuildRequestRecordReceiveTunnelValidData(t *testing.T) {
|
||||||
|
@@ -38,8 +38,10 @@ byte 527 :: reply
|
|||||||
total length: 528
|
total length: 528
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type BuildResponseRecordELGamalAES [528]byte
|
type (
|
||||||
type BuildResponseRecordELGamal [528]byte
|
BuildResponseRecordELGamalAES [528]byte
|
||||||
|
BuildResponseRecordELGamal [528]byte
|
||||||
|
)
|
||||||
|
|
||||||
type BuildResponseRecord struct {
|
type BuildResponseRecord struct {
|
||||||
Hash common.Hash
|
Hash common.Hash
|
||||||
|
343
lib/i2np/doc.md
Normal file
343
lib/i2np/doc.md
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
# i2np
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/i2np"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
I2NP_MESSAGE_TYPE_DATABASE_STORE = 1
|
||||||
|
I2NP_MESSAGE_TYPE_DATABASE_LOOKUP = 2
|
||||||
|
I2NP_MESSAGE_TYPE_DATABASE_SEARCH_REPLY = 3
|
||||||
|
I2NP_MESSAGE_TYPE_DELIVERY_STATUS = 10
|
||||||
|
I2NP_MESSAGE_TYPE_GARLIC = 11
|
||||||
|
I2NP_MESSAGE_TYPE_TUNNEL_DATA = 18
|
||||||
|
I2NP_MESSAGE_TYPE_TUNNEL_GATEWAY = 19
|
||||||
|
I2NP_MESSAGE_TYPE_DATA = 20
|
||||||
|
I2NP_MESSAGE_TYPE_TUNNEL_BUILD = 21
|
||||||
|
I2NP_MESSAGE_TYPE_TUNNEL_BUILD_REPLY = 22
|
||||||
|
I2NP_MESSAGE_TYPE_VARIABLE_TUNNEL_BUILD = 23
|
||||||
|
I2NP_MESSAGE_TYPE_VARIABLE_TUNNEL_BUILD_REPLY = 24
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
var ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA = errors.New("not enough i2np build request record data")
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
var ERR_I2NP_NOT_ENOUGH_DATA = errors.New("not enough i2np header data")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPNTCPData
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPNTCPData(data []byte, size int) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPNTCPMessageChecksum
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPNTCPMessageChecksum(data []byte) (int, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPNTCPMessageExpiration
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPNTCPMessageExpiration(data []byte) (datalib.Date, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPNTCPMessageID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPNTCPMessageID(data []byte) (int, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPNTCPMessageSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPNTCPMessageSize(data []byte) (int, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPSSUMessageExpiration
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPSSUMessageExpiration(data []byte) (datalib.Date, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ReadI2NPType
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPType(data []byte) (int, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type BuildRequestRecord
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BuildRequestRecord struct {
|
||||||
|
ReceiveTunnel tunnel.TunnelID
|
||||||
|
OurIdent common.Hash
|
||||||
|
NextTunnel tunnel.TunnelID
|
||||||
|
NextIdent common.Hash
|
||||||
|
LayerKey session_key.SessionKey
|
||||||
|
IVKey session_key.SessionKey
|
||||||
|
ReplyKey session_key.SessionKey
|
||||||
|
ReplyIV [16]byte
|
||||||
|
Flag int
|
||||||
|
RequestTime time.Time
|
||||||
|
SendMessageID int
|
||||||
|
Padding [29]byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func ReadBuildRequestRecord
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadBuildRequestRecord(data []byte) (BuildRequestRecord, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type BuildRequestRecordElGamal
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BuildRequestRecordElGamal [528]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type BuildRequestRecordElGamalAES
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BuildRequestRecordElGamalAES [528]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type BuildResponseRecord
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BuildResponseRecord struct {
|
||||||
|
Hash common.Hash
|
||||||
|
Padding [495]byte
|
||||||
|
Reply byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type BuildResponseRecordELGamal
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BuildResponseRecordELGamal [528]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type BuildResponseRecordELGamalAES
|
||||||
|
|
||||||
|
```go
|
||||||
|
type BuildResponseRecordELGamalAES [528]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type Data
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Data struct {
|
||||||
|
Length int
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type DatabaseLookup
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DatabaseLookup struct {
|
||||||
|
Key common.Hash
|
||||||
|
From common.Hash
|
||||||
|
Flags byte
|
||||||
|
ReplyTunnelID [4]byte
|
||||||
|
Size int
|
||||||
|
ExcludedPeers []common.Hash
|
||||||
|
ReplyKey session_key.SessionKey
|
||||||
|
|
||||||
|
ReplyTags []session_tag.SessionTag
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type DatabaseSearchReply
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DatabaseSearchReply struct {
|
||||||
|
Key common.Hash
|
||||||
|
Count int
|
||||||
|
PeerHashes []common.Hash
|
||||||
|
From common.Hash
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type DatabaseStore
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DatabaseStore struct {
|
||||||
|
Key common.Hash
|
||||||
|
Type byte
|
||||||
|
ReplyToken [4]byte
|
||||||
|
ReplyTunnelID [4]byte
|
||||||
|
ReplyGateway common.Hash
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type DeliveryStatus
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DeliveryStatus struct {
|
||||||
|
MessageID int
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type Garlic
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Garlic struct {
|
||||||
|
Count int
|
||||||
|
Cloves []GarlicClove
|
||||||
|
Certificate certificate.Certificate
|
||||||
|
MessageID int
|
||||||
|
Expiration time.Time
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type GarlicClove
|
||||||
|
|
||||||
|
```go
|
||||||
|
type GarlicClove struct {
|
||||||
|
DeliveryInstructions GarlicCloveDeliveryInstructions
|
||||||
|
I2NPMessage I2NPMessage
|
||||||
|
CloveID int
|
||||||
|
Expiration time.Time
|
||||||
|
Certificate certificate.Certificate
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type GarlicCloveDeliveryInstructions
|
||||||
|
|
||||||
|
```go
|
||||||
|
type GarlicCloveDeliveryInstructions struct {
|
||||||
|
Flag byte
|
||||||
|
SessionKey session_key.SessionKey
|
||||||
|
Hash common.Hash
|
||||||
|
TunnelID tunnel.TunnelID
|
||||||
|
Delay int
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type GarlicElGamal
|
||||||
|
|
||||||
|
```go
|
||||||
|
type GarlicElGamal []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type I2NPMessage
|
||||||
|
|
||||||
|
```go
|
||||||
|
type I2NPMessage []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type I2NPNTCPHeader
|
||||||
|
|
||||||
|
```go
|
||||||
|
type I2NPNTCPHeader struct {
|
||||||
|
Type int
|
||||||
|
MessageID int
|
||||||
|
Expiration time.Time
|
||||||
|
Size int
|
||||||
|
Checksum int
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func ReadI2NPNTCPHeader
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPNTCPHeader(data []byte) (I2NPNTCPHeader, error)
|
||||||
|
```
|
||||||
|
Read an entire I2NP message and return the parsed header with embedded encrypted
|
||||||
|
data
|
||||||
|
|
||||||
|
#### type I2NPSSUHeader
|
||||||
|
|
||||||
|
```go
|
||||||
|
type I2NPSSUHeader struct {
|
||||||
|
Type int
|
||||||
|
Expiration time.Time
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func ReadI2NPSSUHeader
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ReadI2NPSSUHeader(data []byte) (I2NPSSUHeader, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type TunnelBuild
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelBuild [8]BuildRequestRecord
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type TunnelBuildReply
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelBuildReply [8]BuildResponseRecord
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type TunnelData
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelData [1028]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type TunnelGatway
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelGatway struct {
|
||||||
|
TunnelID tunnel.TunnelID
|
||||||
|
Length int
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type VariableTunnelBuild
|
||||||
|
|
||||||
|
```go
|
||||||
|
type VariableTunnelBuild struct {
|
||||||
|
Count int
|
||||||
|
BuildRequestRecords []BuildRequestRecord
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type VariableTunnelBuildReply
|
||||||
|
|
||||||
|
```go
|
||||||
|
type VariableTunnelBuildReply struct {
|
||||||
|
Count int
|
||||||
|
BuildResponseRecords []BuildResponseRecord
|
||||||
|
}
|
||||||
|
```
|
12
lib/i2np/fuzz/header/doc.md
Normal file
12
lib/i2np/fuzz/header/doc.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# exportable
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/i2np/fuzz/header"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### func Fuzz
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Fuzz(data []byte) int
|
||||||
|
```
|
182
lib/netdb/doc.md
Normal file
182
lib/netdb/doc.md
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
# netdb
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/netdb"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const CacheFileName = "sizecache.txt"
|
||||||
|
```
|
||||||
|
name of file to hold precomputed size of netdb
|
||||||
|
|
||||||
|
#### type Entry
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Entry struct {
|
||||||
|
*router_info.RouterInfo
|
||||||
|
*lease_set.LeaseSet
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
netdb entry wraps a router info and provides serialization
|
||||||
|
|
||||||
|
#### func (*Entry) ReadFrom
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *Entry) ReadFrom(r io.Reader) (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Entry) WriteTo
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (e *Entry) WriteTo(w io.Writer) (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type NetworkDatabase
|
||||||
|
|
||||||
|
```go
|
||||||
|
type NetworkDatabase interface {
|
||||||
|
// obtain a RouterInfo by its hash locally
|
||||||
|
// return a RouterInfo if we found it locally
|
||||||
|
// return nil if the RouterInfo cannot be found locally
|
||||||
|
GetRouterInfo(hash common.Hash) router_info.RouterInfo
|
||||||
|
|
||||||
|
// store a router info locally
|
||||||
|
StoreRouterInfo(ri router_info.RouterInfo)
|
||||||
|
|
||||||
|
// try obtaining more peers with a bootstrap instance until we get minRouters number of router infos
|
||||||
|
// returns error if bootstrap.GetPeers returns an error otherwise returns nil
|
||||||
|
Reseed(b bootstrap.Bootstrap, minRouters int) error
|
||||||
|
|
||||||
|
// return how many router infos we have
|
||||||
|
Size() int
|
||||||
|
|
||||||
|
// Recaculate size of netdb from backend
|
||||||
|
RecalculateSize() error
|
||||||
|
|
||||||
|
// ensure underlying resources exist , i.e. directories, files, configs
|
||||||
|
Ensure() error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
i2p network database, storage of i2p RouterInfos
|
||||||
|
|
||||||
|
#### type Resolver
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Resolver interface {
|
||||||
|
// resolve a router info by hash
|
||||||
|
// return a chan that yields the found RouterInfo or nil if it could not be found after timeout
|
||||||
|
Lookup(hash common.Hash, timeout time.Duration) chan router_info.RouterInfo
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
resolves unknown RouterInfos given the hash of their RouterIdentity
|
||||||
|
|
||||||
|
#### func KademliaResolver
|
||||||
|
|
||||||
|
```go
|
||||||
|
func KademliaResolver(netDb NetworkDatabase, pool *tunnel.Pool) (r Resolver)
|
||||||
|
```
|
||||||
|
create a new resolver that stores result into a NetworkDatabase and uses a
|
||||||
|
tunnel pool for the lookup
|
||||||
|
|
||||||
|
#### type StdNetDB
|
||||||
|
|
||||||
|
```go
|
||||||
|
type StdNetDB struct {
|
||||||
|
DB string
|
||||||
|
RouterInfos map[common.Hash]Entry
|
||||||
|
LeaseSets map[common.Hash]Entry
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
standard network database implementation using local filesystem skiplist
|
||||||
|
|
||||||
|
#### func NewStdNetDB
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewStdNetDB(db string) StdNetDB
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*StdNetDB) CheckFilePathValid
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) CheckFilePathValid(fpath string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Create
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Create() (err error)
|
||||||
|
```
|
||||||
|
create base network database directory
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Ensure
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Ensure() (err error)
|
||||||
|
```
|
||||||
|
ensure that the network database exists
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Exists
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Exists() bool
|
||||||
|
```
|
||||||
|
return true if the network db directory exists and is writable
|
||||||
|
|
||||||
|
#### func (*StdNetDB) GetRouterInfo
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) GetRouterInfo(hash common.Hash) (chnl chan router_info.RouterInfo)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Path
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Path() string
|
||||||
|
```
|
||||||
|
get netdb path
|
||||||
|
|
||||||
|
#### func (*StdNetDB) RecalculateSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) RecalculateSize() (err error)
|
||||||
|
```
|
||||||
|
recalculateSize recalculates cached size of netdb
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Reseed
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Reseed(b bootstrap.Bootstrap, minRouters int) (err error)
|
||||||
|
```
|
||||||
|
reseed if we have less than minRouters known routers returns error if reseed
|
||||||
|
failed
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Save
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Save() (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*StdNetDB) SaveEntry
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) SaveEntry(e *Entry) (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*StdNetDB) Size
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) Size() (routers int)
|
||||||
|
```
|
||||||
|
return how many routers we know about in our network database
|
||||||
|
|
||||||
|
#### func (*StdNetDB) SkiplistFile
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (db *StdNetDB) SkiplistFile(hash common.Hash) (fpath string)
|
||||||
|
```
|
||||||
|
get the skiplist file that a RouterInfo with this hash would go in
|
@@ -3,13 +3,15 @@ package netdb
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/lease_set"
|
||||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||||
)
|
)
|
||||||
|
|
||||||
// netdb entry
|
// netdb entry
|
||||||
// wraps a router info and provides serialization
|
// wraps a router info and provides serialization
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
ri router_info.RouterInfo
|
*router_info.RouterInfo
|
||||||
|
*lease_set.LeaseSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Entry) WriteTo(w io.Writer) (err error) {
|
func (e *Entry) WriteTo(w io.Writer) (err error) {
|
||||||
|
27
lib/netdb/reseed/doc.md
Normal file
27
lib/netdb/reseed/doc.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# reseed
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/netdb/reseed"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
I2pUserAgent = "Wget/1.11.4"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Reseed
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Reseed struct {
|
||||||
|
net.Dialer
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (Reseed) SingleReseed
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r Reseed) SingleReseed(uri string) ([]router_info.RouterInfo, error)
|
||||||
|
```
|
94
lib/netdb/reseed/reseed.go
Normal file
94
lib/netdb/reseed/reseed.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package reseed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/eyedeekay/go-unzip/pkg/unzip"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/config"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/su3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
I2pUserAgent = "Wget/1.11.4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Reseed struct {
|
||||||
|
net.Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Reseed) SingleReseed(uri string) ([]router_info.RouterInfo, error) {
|
||||||
|
transport := http.Transport{
|
||||||
|
DialContext: r.DialContext,
|
||||||
|
}
|
||||||
|
client := http.Client{
|
||||||
|
Transport: &transport,
|
||||||
|
}
|
||||||
|
URL, err := url.Parse(uri)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
header := http.Header{}
|
||||||
|
header.Add("user-agent", "Wget/1.11.4")
|
||||||
|
request := http.Request{
|
||||||
|
URL: URL,
|
||||||
|
Header: header,
|
||||||
|
}
|
||||||
|
response, err := client.Do(&request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
su3file, err := su3.Read(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if su3file.FileType == su3.ZIP {
|
||||||
|
if su3file.ContentType == su3.RESEED {
|
||||||
|
if err == nil {
|
||||||
|
content, err := io.ReadAll(su3file.Content(""))
|
||||||
|
if err == nil {
|
||||||
|
signature, err := io.ReadAll(su3file.Signature())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Println("warning: this doesn't validate the signature yet", signature)
|
||||||
|
}
|
||||||
|
zip := filepath.Join(config.RouterConfigProperties.NetDb.Path, "reseed.zip")
|
||||||
|
err = os.WriteFile(zip, content, 0o644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// content is a zip file, unzip it and get the files
|
||||||
|
files, err := unzip.New().Extract(zip, config.RouterConfigProperties.NetDb.Path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(files) <= 0 {
|
||||||
|
return nil, fmt.Errorf("error: reseed appears to have no content")
|
||||||
|
}
|
||||||
|
var ris []router_info.RouterInfo
|
||||||
|
for _, f := range files {
|
||||||
|
riB, err := os.ReadFile(f)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ri, _, err := router_info.ReadRouterInfo(riB)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ris = append(ris, ri)
|
||||||
|
}
|
||||||
|
err = os.Remove(zip)
|
||||||
|
return ris, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("error: undefined reseed error")
|
||||||
|
}
|
126
lib/netdb/std.go
126
lib/netdb/std.go
@@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/bootstrap"
|
"github.com/go-i2p/go-i2p/lib/bootstrap"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/base32"
|
||||||
"github.com/go-i2p/go-i2p/lib/common/base64"
|
"github.com/go-i2p/go-i2p/lib/common/base64"
|
||||||
common "github.com/go-i2p/go-i2p/lib/common/data"
|
common "github.com/go-i2p/go-i2p/lib/common/data"
|
||||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||||
@@ -19,43 +20,66 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// standard network database implementation using local filesystem skiplist
|
// standard network database implementation using local filesystem skiplist
|
||||||
type StdNetDB string
|
type StdNetDB struct {
|
||||||
|
DB string
|
||||||
|
RouterInfos map[common.Hash]Entry
|
||||||
|
LeaseSets map[common.Hash]Entry
|
||||||
|
}
|
||||||
|
|
||||||
func (db StdNetDB) GetRouterInfo(hash common.Hash) (chnl chan router_info.RouterInfo) {
|
func NewStdNetDB(db string) StdNetDB {
|
||||||
fname := db.SkiplistFile(hash)
|
return StdNetDB{
|
||||||
f, err := os.Open(fname)
|
DB: db,
|
||||||
if err != nil {
|
RouterInfos: make(map[common.Hash]Entry),
|
||||||
return nil
|
LeaseSets: make(map[common.Hash]Entry),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *StdNetDB) GetRouterInfo(hash common.Hash) (chnl chan router_info.RouterInfo) {
|
||||||
|
if ri, ok := db.RouterInfos[hash]; ok {
|
||||||
|
chnl <- *ri.RouterInfo
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fname := db.SkiplistFile(hash)
|
||||||
buff := new(bytes.Buffer)
|
buff := new(bytes.Buffer)
|
||||||
_, err = io.Copy(buff, f)
|
if f, err := os.Open(fname); err != nil {
|
||||||
f.Close()
|
return nil
|
||||||
|
} else {
|
||||||
|
if _, err := io.Copy(buff, f); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
}
|
||||||
chnl = make(chan router_info.RouterInfo)
|
chnl = make(chan router_info.RouterInfo)
|
||||||
ri, _, err := router_info.ReadRouterInfo(buff.Bytes())
|
ri, _, err := router_info.ReadRouterInfo(buff.Bytes())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
if _, ok := db.RouterInfos[hash]; !ok {
|
||||||
|
db.RouterInfos[hash] = Entry{
|
||||||
|
RouterInfo: &ri,
|
||||||
|
}
|
||||||
|
}
|
||||||
chnl <- ri
|
chnl <- ri
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the skiplist file that a RouterInfo with this hash would go in
|
// get the skiplist file that a RouterInfo with this hash would go in
|
||||||
func (db StdNetDB) SkiplistFile(hash common.Hash) (fpath string) {
|
func (db *StdNetDB) SkiplistFile(hash common.Hash) (fpath string) {
|
||||||
fname := base64.EncodeToString(hash[:])
|
fname := base64.EncodeToString(hash[:])
|
||||||
fpath = filepath.Join(db.Path(), fmt.Sprintf("r%c", fname[0]), fmt.Sprintf("routerInfo-%s.dat", fname))
|
fpath = filepath.Join(db.Path(), fmt.Sprintf("r%c", fname[0]), fmt.Sprintf("routerInfo-%s.dat", fname))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get netdb path
|
// get netdb path
|
||||||
func (db StdNetDB) Path() string {
|
func (db *StdNetDB) Path() string {
|
||||||
return string(db)
|
return string(db.DB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return how many routers we know about in our network database
|
// return how many routers we know about in our network database
|
||||||
func (db StdNetDB) Size() (routers int) {
|
func (db *StdNetDB) Size() (routers int) {
|
||||||
// TODO: implement this
|
// TODO: implement this
|
||||||
var err error
|
var err error
|
||||||
var data []byte
|
var data []byte
|
||||||
if !util.CheckFileExists(db.cacheFilePath()) {
|
if !util.CheckFileExists(db.cacheFilePath()) || util.CheckFileAge(db.cacheFilePath(), 2) || len(db.RouterInfos) == 0 {
|
||||||
// regenerate
|
// regenerate
|
||||||
err = db.RecalculateSize()
|
err = db.RecalculateSize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -74,33 +98,63 @@ func (db StdNetDB) Size() (routers int) {
|
|||||||
const CacheFileName = "sizecache.txt"
|
const CacheFileName = "sizecache.txt"
|
||||||
|
|
||||||
// get filepath for storing netdb info cache
|
// get filepath for storing netdb info cache
|
||||||
func (db StdNetDB) cacheFilePath() string {
|
func (db *StdNetDB) cacheFilePath() string {
|
||||||
return filepath.Join(db.Path(), CacheFileName)
|
return filepath.Join(db.Path(), CacheFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db StdNetDB) CheckFilePathValid(fpath string) bool {
|
func (db *StdNetDB) CheckFilePathValid(fpath string) bool {
|
||||||
// TODO: make this better
|
// TODO: make this better
|
||||||
return strings.HasSuffix(fpath, ".dat")
|
return strings.HasSuffix(fpath, ".dat")
|
||||||
}
|
}
|
||||||
|
|
||||||
// recalculateSize recalculates cached size of netdb
|
// recalculateSize recalculates cached size of netdb
|
||||||
func (db StdNetDB) RecalculateSize() (err error) {
|
func (db *StdNetDB) RecalculateSize() (err error) {
|
||||||
fpath := db.cacheFilePath()
|
|
||||||
count := 0
|
count := 0
|
||||||
err = filepath.Walk(fpath, func(fname string, info os.FileInfo, err error) error {
|
err = filepath.Walk(db.Path(), func(fname string, info os.FileInfo, err error) error {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
|
if !strings.HasPrefix(fname, db.Path()) {
|
||||||
|
if db.Path() == fname {
|
||||||
|
log.Info("path==name time to exit")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
log.Info("Outside of netDb dir time to exit", db.Path(), " ", fname)
|
||||||
|
return err
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if db.CheckFilePathValid(fname) {
|
if db.CheckFilePathValid(fname) {
|
||||||
// TODO: make sure it's in a skiplist directory
|
log.Println("Reading in file:", fname)
|
||||||
|
b, err := os.ReadFile(fname)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ri, _, err := router_info.ReadRouterInfo(b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ih := ri.IdentHash().Bytes()
|
||||||
|
log.Printf("Read in IdentHash: %s", base32.EncodeToString(ih[:]))
|
||||||
|
for _, addr := range ri.RouterAddresses() {
|
||||||
|
log.Println(string(addr.Bytes()))
|
||||||
|
}
|
||||||
|
if ent, ok := db.RouterInfos[ih]; !ok {
|
||||||
|
db.RouterInfos[ri.IdentHash()] = Entry{
|
||||||
|
RouterInfo: &ri,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Println("entry previously found in table", ent, fname)
|
||||||
|
}
|
||||||
|
ri = router_info.RouterInfo{}
|
||||||
count++
|
count++
|
||||||
|
} else {
|
||||||
|
log.Println("Invalid path error")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
str := fmt.Sprintf("%d", count)
|
str := fmt.Sprintf("%d", count)
|
||||||
var f *os.File
|
var f *os.File
|
||||||
f, err = os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY, 0600)
|
f, err = os.OpenFile(db.cacheFilePath(), os.O_CREATE|os.O_WRONLY, 0o600)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = io.WriteString(f, str)
|
_, err = io.WriteString(f, str)
|
||||||
f.Close()
|
f.Close()
|
||||||
@@ -110,7 +164,7 @@ func (db StdNetDB) RecalculateSize() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return true if the network db directory exists and is writable
|
// return true if the network db directory exists and is writable
|
||||||
func (db StdNetDB) Exists() bool {
|
func (db *StdNetDB) Exists() bool {
|
||||||
p := db.Path()
|
p := db.Path()
|
||||||
// check root directory
|
// check root directory
|
||||||
_, err := os.Stat(p)
|
_, err := os.Stat(p)
|
||||||
@@ -125,12 +179,11 @@ func (db StdNetDB) Exists() bool {
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db StdNetDB) SaveEntry(e *Entry) (err error) {
|
func (db *StdNetDB) SaveEntry(e *Entry) (err error) {
|
||||||
var f io.WriteCloser
|
var f io.WriteCloser
|
||||||
var h common.Hash
|
h := e.RouterInfo.IdentHash()
|
||||||
h = e.ri.IdentHash()
|
// if err == nil {
|
||||||
//if err == nil {
|
f, err = os.OpenFile(db.SkiplistFile(h), os.O_WRONLY|os.O_CREATE, 0o700)
|
||||||
f, err = os.OpenFile(db.SkiplistFile(h), os.O_WRONLY|os.O_CREATE, 0700)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = e.WriteTo(f)
|
err = e.WriteTo(f)
|
||||||
f.Close()
|
f.Close()
|
||||||
@@ -142,14 +195,27 @@ func (db StdNetDB) SaveEntry(e *Entry) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *StdNetDB) Save() (err error) {
|
||||||
|
for _, dbe := range db.RouterInfos {
|
||||||
|
if e := db.SaveEntry(&dbe); e != nil {
|
||||||
|
err = e
|
||||||
|
// TODO: log this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// reseed if we have less than minRouters known routers
|
// reseed if we have less than minRouters known routers
|
||||||
// returns error if reseed failed
|
// returns error if reseed failed
|
||||||
func (db StdNetDB) Reseed(b bootstrap.Bootstrap, minRouters int) (err error) {
|
func (db *StdNetDB) Reseed(b bootstrap.Bootstrap, minRouters int) (err error) {
|
||||||
|
if db.Size() > minRouters {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that the network database exists
|
// ensure that the network database exists
|
||||||
func (db StdNetDB) Ensure() (err error) {
|
func (db *StdNetDB) Ensure() (err error) {
|
||||||
if !db.Exists() {
|
if !db.Exists() {
|
||||||
err = db.Create()
|
err = db.Create()
|
||||||
}
|
}
|
||||||
@@ -157,8 +223,8 @@ func (db StdNetDB) Ensure() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create base network database directory
|
// create base network database directory
|
||||||
func (db StdNetDB) Create() (err error) {
|
func (db *StdNetDB) Create() (err error) {
|
||||||
mode := os.FileMode(0700)
|
mode := os.FileMode(0o700)
|
||||||
p := db.Path()
|
p := db.Path()
|
||||||
log.Infof("Create network database in %s", p)
|
log.Infof("Create network database in %s", p)
|
||||||
|
|
||||||
|
58
lib/router/doc.md
Normal file
58
lib/router/doc.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# router
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/router"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### type Router
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Router struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
i2p router type
|
||||||
|
|
||||||
|
#### func CreateRouter
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CreateRouter() (r *Router, err error)
|
||||||
|
```
|
||||||
|
create router with default configuration
|
||||||
|
|
||||||
|
#### func FromConfig
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FromConfig(c *config.RouterConfig) (r *Router, err error)
|
||||||
|
```
|
||||||
|
create router from configuration
|
||||||
|
|
||||||
|
#### func (*Router) Close
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Router) Close() error
|
||||||
|
```
|
||||||
|
Close closes any internal state and finallizes router resources so that nothing
|
||||||
|
can start up again
|
||||||
|
|
||||||
|
#### func (*Router) Start
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Router) Start()
|
||||||
|
```
|
||||||
|
Start starts router mainloop
|
||||||
|
|
||||||
|
#### func (*Router) Stop
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Router) Stop()
|
||||||
|
```
|
||||||
|
Stop starts stopping internal state of router
|
||||||
|
|
||||||
|
#### func (*Router) Wait
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Router) Wait()
|
||||||
|
```
|
||||||
|
Wait blocks until router is fully stopped
|
@@ -1,10 +1,11 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/config"
|
"github.com/go-i2p/go-i2p/lib/config"
|
||||||
"github.com/go-i2p/go-i2p/lib/netdb"
|
"github.com/go-i2p/go-i2p/lib/netdb"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// i2p router type
|
// i2p router type
|
||||||
@@ -17,7 +18,7 @@ type Router struct {
|
|||||||
|
|
||||||
// create router with default configuration
|
// create router with default configuration
|
||||||
func CreateRouter() (r *Router, err error) {
|
func CreateRouter() (r *Router, err error) {
|
||||||
cfg := config.DefaultRouterConfig
|
cfg := config.RouterConfigProperties
|
||||||
r, err = FromConfig(cfg)
|
r, err = FromConfig(cfg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -61,22 +62,28 @@ func (r *Router) Start() {
|
|||||||
|
|
||||||
// run i2p router mainloop
|
// run i2p router mainloop
|
||||||
func (r *Router) mainloop() {
|
func (r *Router) mainloop() {
|
||||||
r.ndb = netdb.StdNetDB(r.cfg.NetDb.Path)
|
r.ndb = netdb.NewStdNetDB(r.cfg.NetDb.Path)
|
||||||
// make sure the netdb is ready
|
// make sure the netdb is ready
|
||||||
err := r.ndb.Ensure()
|
var e error
|
||||||
if err == nil {
|
if err := r.ndb.Ensure(); err != nil {
|
||||||
|
e = err
|
||||||
|
}
|
||||||
|
if sz := r.ndb.Size(); sz >= 0 {
|
||||||
|
log.Info("NetDB Size:", sz)
|
||||||
|
}
|
||||||
|
if e == nil {
|
||||||
// netdb ready
|
// netdb ready
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(Router) mainloop",
|
"at": "(Router) mainloop",
|
||||||
}).Info("Router ready")
|
}).Info("Router ready")
|
||||||
for err == nil {
|
for e == nil {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// netdb failed
|
// netdb failed
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"at": "(Router) mainloop",
|
"at": "(Router) mainloop",
|
||||||
"reason": err.Error(),
|
"reason": e.Error(),
|
||||||
}).Error("Netdb Startup failed")
|
}).Error("Netdb Startup failed")
|
||||||
r.Stop()
|
r.Stop()
|
||||||
}
|
}
|
||||||
|
189
lib/su3/doc.md
Normal file
189
lib/su3/doc.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# su3
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/su3"
|
||||||
|
|
||||||
|
Package su3 implements reading the SU3 file format.
|
||||||
|
|
||||||
|
SU3 files provide content that is signed by a known identity. They are used to
|
||||||
|
distribute many types of data, including reseed files, plugins, blocklists, and
|
||||||
|
more.
|
||||||
|
|
||||||
|
See: https://geti2p.net/spec/updates#su3-file-specification
|
||||||
|
|
||||||
|
The Read() function takes an io.Reader, and it returns a *SU3. The *SU3 contains
|
||||||
|
the SU3 file metadata, such as the type of the content and the signer ID. In
|
||||||
|
order to get the file contents, one must pass in the public key associated with
|
||||||
|
the file's signer, so that the signature can be validated. The content can still
|
||||||
|
be read without passing in the key, but after returning the full content the
|
||||||
|
error ErrInvalidSignature will be returned.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
// Let's say we are reading an SU3 file from an HTTP body, which is an io.Reader.
|
||||||
|
su3File, err := su3.Read(body)
|
||||||
|
if err != nil {
|
||||||
|
// Handle error.
|
||||||
|
}
|
||||||
|
// Look up this signer's key.
|
||||||
|
key := somehow_lookup_the_key(su3File.SignerID)
|
||||||
|
// Read the content.
|
||||||
|
contentReader := su3File.Content(key)
|
||||||
|
bytes, err := ioutil.ReadAll(contentReader)
|
||||||
|
if errors.Is(err, su3.ErrInvalidSignature) {
|
||||||
|
// The signature is invalid, OR a nil key was provided.
|
||||||
|
} else if err != nil {
|
||||||
|
// Handle error.
|
||||||
|
}
|
||||||
|
|
||||||
|
If you want to parse from a []byte, you can wrap it like this:
|
||||||
|
|
||||||
|
mySU3FileBytes := []byte{0x00, 0x01, 0x02, 0x03}
|
||||||
|
su3File, err := su3.Read(bytes.NewReader(mySU3FileBytes))
|
||||||
|
|
||||||
|
One of the advantages of this library's design is that you can avoid buffering
|
||||||
|
the file contents in memory. Here's how you would stream from an HTTP body
|
||||||
|
directly to disk:
|
||||||
|
|
||||||
|
su3File, err := su3.Read(body)
|
||||||
|
if err != nil {
|
||||||
|
// Handle error.
|
||||||
|
}
|
||||||
|
// Look up this signer's key.
|
||||||
|
key := somehow_lookup_the_key(su3File.SignerID)
|
||||||
|
// Stream directly to disk.
|
||||||
|
f, err := os.Create("my_file.txt")
|
||||||
|
if err != nil {
|
||||||
|
// Handle error.
|
||||||
|
}
|
||||||
|
_, err := io.Copy(f, su3File.Content(key))
|
||||||
|
if errors.Is(err, su3.ErrInvalidSignature) {
|
||||||
|
// The signature is invalid, OR a nil key was provided.
|
||||||
|
// Don't trust the file, delete it!
|
||||||
|
} else if err != nil {
|
||||||
|
// Handle error.
|
||||||
|
}
|
||||||
|
|
||||||
|
Note: if you want to read the content, the Content() io.Reader must be read
|
||||||
|
*before* the Signature() io.Reader. If you read the signature first, the content
|
||||||
|
bytes will be thrown away. If you then attempt to read the content, you will get
|
||||||
|
an error. For clarification, see TestReadSignatureFirst.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
var (
|
||||||
|
ErrMissingMagicBytes = errors.New("missing magic bytes")
|
||||||
|
ErrMissingUnusedByte6 = errors.New("missing unused byte 6")
|
||||||
|
ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version")
|
||||||
|
ErrMissingSignatureType = errors.New("missing or invalid signature type")
|
||||||
|
ErrUnsupportedSignatureType = errors.New("unsupported signature type")
|
||||||
|
ErrMissingSignatureLength = errors.New("missing signature length")
|
||||||
|
ErrMissingUnusedByte12 = errors.New("missing unused byte 12")
|
||||||
|
ErrMissingVersionLength = errors.New("missing version length")
|
||||||
|
ErrVersionTooShort = errors.New("version length too short")
|
||||||
|
ErrMissingUnusedByte14 = errors.New("missing unused byte 14")
|
||||||
|
ErrMissingSignerIDLength = errors.New("missing signer ID length")
|
||||||
|
ErrMissingContentLength = errors.New("missing content length")
|
||||||
|
ErrMissingUnusedByte24 = errors.New("missing unused byte 24")
|
||||||
|
ErrMissingFileType = errors.New("missing or invalid file type")
|
||||||
|
ErrMissingUnusedByte26 = errors.New("missing unused byte 26")
|
||||||
|
ErrMissingContentType = errors.New("missing or invalid content type")
|
||||||
|
ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39")
|
||||||
|
ErrMissingVersion = errors.New("missing version")
|
||||||
|
ErrMissingSignerID = errors.New("missing signer ID")
|
||||||
|
ErrMissingContent = errors.New("missing content")
|
||||||
|
ErrMissingSignature = errors.New("missing signature")
|
||||||
|
ErrInvalidPublicKey = errors.New("invalid public key")
|
||||||
|
ErrInvalidSignature = errors.New("invalid signature")
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type ContentType
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ContentType string
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
UNKNOWN ContentType = "unknown"
|
||||||
|
ROUTER_UPDATE ContentType = "router_update"
|
||||||
|
PLUGIN ContentType = "plugin"
|
||||||
|
RESEED ContentType = "reseed"
|
||||||
|
NEWS ContentType = "news"
|
||||||
|
BLOCKLIST ContentType = "blocklist"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type FileType
|
||||||
|
|
||||||
|
```go
|
||||||
|
type FileType string
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
ZIP FileType = "zip"
|
||||||
|
XML FileType = "xml"
|
||||||
|
HTML FileType = "html"
|
||||||
|
XML_GZIP FileType = "xml.gz"
|
||||||
|
TXT_GZIP FileType = "txt.gz"
|
||||||
|
DMG FileType = "dmg"
|
||||||
|
EXE FileType = "exe"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type SU3
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SU3 struct {
|
||||||
|
SignatureType SignatureType
|
||||||
|
SignatureLength uint16
|
||||||
|
ContentLength uint64
|
||||||
|
FileType FileType
|
||||||
|
ContentType ContentType
|
||||||
|
Version string
|
||||||
|
SignerID string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func Read
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Read(reader io.Reader) (su3 *SU3, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*SU3) Content
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (su3 *SU3) Content(publicKey interface{}) io.Reader
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*SU3) Signature
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (su3 *SU3) Signature() io.Reader
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type SignatureType
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SignatureType string
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
DSA_SHA1 SignatureType = "DSA-SHA1"
|
||||||
|
ECDSA_SHA256_P256 SignatureType = "ECDSA-SHA256-P256"
|
||||||
|
ECDSA_SHA384_P384 SignatureType = "ECDSA-SHA384-P384"
|
||||||
|
ECDSA_SHA512_P521 SignatureType = "ECDSA-SHA512-P521"
|
||||||
|
RSA_SHA256_2048 SignatureType = "RSA-SHA256-2048"
|
||||||
|
RSA_SHA384_3072 SignatureType = "RSA-SHA384-3072"
|
||||||
|
RSA_SHA512_4096 SignatureType = "RSA-SHA512-4096"
|
||||||
|
EdDSA_SHA512_Ed25519ph SignatureType = "EdDSA-SHA512-Ed25519ph"
|
||||||
|
)
|
||||||
|
```
|
@@ -146,29 +146,31 @@ var contentTypes = map[byte]ContentType{
|
|||||||
0x05: BLOCKLIST,
|
0x05: BLOCKLIST,
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrMissingMagicBytes = errors.New("missing magic bytes")
|
var (
|
||||||
var ErrMissingUnusedByte6 = errors.New("missing unused byte 6")
|
ErrMissingMagicBytes = errors.New("missing magic bytes")
|
||||||
var ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version")
|
ErrMissingUnusedByte6 = errors.New("missing unused byte 6")
|
||||||
var ErrMissingSignatureType = errors.New("missing or invalid signature type")
|
ErrMissingFileFormatVersion = errors.New("missing or incorrect file format version")
|
||||||
var ErrUnsupportedSignatureType = errors.New("unsupported signature type")
|
ErrMissingSignatureType = errors.New("missing or invalid signature type")
|
||||||
var ErrMissingSignatureLength = errors.New("missing signature length")
|
ErrUnsupportedSignatureType = errors.New("unsupported signature type")
|
||||||
var ErrMissingUnusedByte12 = errors.New("missing unused byte 12")
|
ErrMissingSignatureLength = errors.New("missing signature length")
|
||||||
var ErrMissingVersionLength = errors.New("missing version length")
|
ErrMissingUnusedByte12 = errors.New("missing unused byte 12")
|
||||||
var ErrVersionTooShort = errors.New("version length too short")
|
ErrMissingVersionLength = errors.New("missing version length")
|
||||||
var ErrMissingUnusedByte14 = errors.New("missing unused byte 14")
|
ErrVersionTooShort = errors.New("version length too short")
|
||||||
var ErrMissingSignerIDLength = errors.New("missing signer ID length")
|
ErrMissingUnusedByte14 = errors.New("missing unused byte 14")
|
||||||
var ErrMissingContentLength = errors.New("missing content length")
|
ErrMissingSignerIDLength = errors.New("missing signer ID length")
|
||||||
var ErrMissingUnusedByte24 = errors.New("missing unused byte 24")
|
ErrMissingContentLength = errors.New("missing content length")
|
||||||
var ErrMissingFileType = errors.New("missing or invalid file type")
|
ErrMissingUnusedByte24 = errors.New("missing unused byte 24")
|
||||||
var ErrMissingUnusedByte26 = errors.New("missing unused byte 26")
|
ErrMissingFileType = errors.New("missing or invalid file type")
|
||||||
var ErrMissingContentType = errors.New("missing or invalid content type")
|
ErrMissingUnusedByte26 = errors.New("missing unused byte 26")
|
||||||
var ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39")
|
ErrMissingContentType = errors.New("missing or invalid content type")
|
||||||
var ErrMissingVersion = errors.New("missing version")
|
ErrMissingUnusedBytes28To39 = errors.New("missing unused bytes 28-39")
|
||||||
var ErrMissingSignerID = errors.New("missing signer ID")
|
ErrMissingVersion = errors.New("missing version")
|
||||||
var ErrMissingContent = errors.New("missing content")
|
ErrMissingSignerID = errors.New("missing signer ID")
|
||||||
var ErrMissingSignature = errors.New("missing signature")
|
ErrMissingContent = errors.New("missing content")
|
||||||
var ErrInvalidPublicKey = errors.New("invalid public key")
|
ErrMissingSignature = errors.New("missing signature")
|
||||||
var ErrInvalidSignature = errors.New("invalid signature")
|
ErrInvalidPublicKey = errors.New("invalid public key")
|
||||||
|
ErrInvalidSignature = errors.New("invalid signature")
|
||||||
|
)
|
||||||
|
|
||||||
const magicBytes = "I2Psu3"
|
const magicBytes = "I2Psu3"
|
||||||
|
|
||||||
|
@@ -9,11 +9,12 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fileReader(t *testing.T, filename string) io.Reader {
|
func fileReader(t *testing.T, filename string) io.Reader {
|
||||||
@@ -60,11 +61,13 @@ func fileRSAPubKey(t *testing.T, filename string) *rsa.PublicKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This fake data is generated in TestMain.
|
// This fake data is generated in TestMain.
|
||||||
var aliceFakeKey *rsa.PrivateKey
|
var (
|
||||||
var bobFakeKey *rsa.PrivateKey
|
aliceFakeKey *rsa.PrivateKey
|
||||||
var aliceContent []byte
|
bobFakeKey *rsa.PrivateKey
|
||||||
var aliceSignature []byte
|
aliceContent []byte
|
||||||
var aliceSU3 []byte
|
aliceSignature []byte
|
||||||
|
aliceSU3 []byte
|
||||||
|
)
|
||||||
|
|
||||||
func TestRead(t *testing.T) {
|
func TestRead(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
122
lib/transport/doc.md
Normal file
122
lib/transport/doc.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# transport
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/transport"
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
i2np messages transports
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
var ErrNoTransportAvailable = errors.New("no transports available")
|
||||||
|
```
|
||||||
|
error for when we have no transports available to use
|
||||||
|
|
||||||
|
#### type Transport
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Transport interface {
|
||||||
|
// Accept accepts an incoming session.
|
||||||
|
Accept() (net.Conn, error)
|
||||||
|
|
||||||
|
// Addr returns an
|
||||||
|
Addr() net.Addr
|
||||||
|
|
||||||
|
// Set the router identity for this transport.
|
||||||
|
// will bind if the underlying socket is not already
|
||||||
|
// if the underlying socket is already bound update the RouterIdentity
|
||||||
|
// returns any errors that happen if they do
|
||||||
|
SetIdentity(ident router_identity.RouterIdentity) error
|
||||||
|
|
||||||
|
// Obtain a transport session with a router given its RouterInfo.
|
||||||
|
// If a session with this router is NOT already made attempt to create one and block until made or until an error happens
|
||||||
|
// returns an established TransportSession and nil on success
|
||||||
|
// returns nil and an error on error
|
||||||
|
GetSession(routerInfo router_info.RouterInfo) (TransportSession, error)
|
||||||
|
|
||||||
|
// return true if a routerInfo is compatable with this transport
|
||||||
|
Compatable(routerInfo router_info.RouterInfo) bool
|
||||||
|
|
||||||
|
// close the transport cleanly
|
||||||
|
// blocks until done
|
||||||
|
// returns an error if one happens
|
||||||
|
Close() error
|
||||||
|
|
||||||
|
// get the name of this tranport as a string
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type TransportMuxer
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TransportMuxer struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
muxes multiple transports into 1 Transport implements transport.Transport
|
||||||
|
|
||||||
|
#### func Mux
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Mux(t ...Transport) (tmux *TransportMuxer)
|
||||||
|
```
|
||||||
|
mux a bunch of transports together
|
||||||
|
|
||||||
|
#### func (*TransportMuxer) Close
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tmux *TransportMuxer) Close() (err error)
|
||||||
|
```
|
||||||
|
close every transport that this transport muxer has
|
||||||
|
|
||||||
|
#### func (*TransportMuxer) Compatable
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tmux *TransportMuxer) Compatable(routerInfo router_info.RouterInfo) (compat bool)
|
||||||
|
```
|
||||||
|
is there a transport that we mux that is compatable with this router info?
|
||||||
|
|
||||||
|
#### func (*TransportMuxer) GetSession
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tmux *TransportMuxer) GetSession(routerInfo router_info.RouterInfo) (s TransportSession, err error)
|
||||||
|
```
|
||||||
|
get a transport session given a router info return session and nil if successful
|
||||||
|
return nil and ErrNoTransportAvailable if we failed to get a session
|
||||||
|
|
||||||
|
#### func (*TransportMuxer) Name
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tmux *TransportMuxer) Name() string
|
||||||
|
```
|
||||||
|
the name of this transport with the names of all the ones that we mux
|
||||||
|
|
||||||
|
#### func (*TransportMuxer) SetIdentity
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tmux *TransportMuxer) SetIdentity(ident router_identity.RouterIdentity) (err error)
|
||||||
|
```
|
||||||
|
set the identity for every transport
|
||||||
|
|
||||||
|
#### type TransportSession
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TransportSession interface {
|
||||||
|
// queue an i2np message to be sent over the session
|
||||||
|
// will block as long as the send queue is full
|
||||||
|
// does not block if the queue is not full
|
||||||
|
QueueSendI2NP(msg i2np.I2NPMessage)
|
||||||
|
// return how many i2np messages are not completely sent yet
|
||||||
|
SendQueueSize() int
|
||||||
|
// blocking read the next fully recv'd i2np message from this session
|
||||||
|
ReadNextI2NP() (i2np.I2NPMessage, error)
|
||||||
|
// close the session cleanly
|
||||||
|
// returns any errors that happen while closing the session
|
||||||
|
Close() error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
a session between 2 routers for tranmitting i2np messages securly
|
68
lib/transport/messages/doc.md
Normal file
68
lib/transport/messages/doc.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# ntcp
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/transport/messages"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
MessageTypeSessionRequest = 0x00
|
||||||
|
MessageTypeSessionCreated = 0x01
|
||||||
|
MessageTypeSessionConfirmed = 0x02
|
||||||
|
MessageTypeData = 0x03
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Message
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Message interface {
|
||||||
|
// Type returns the message type
|
||||||
|
Type() MessageType
|
||||||
|
// Payload returns the message payload
|
||||||
|
Payload() []byte
|
||||||
|
// PayloadSize returns the message payload size
|
||||||
|
PayloadSize() int
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type MessageType
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MessageType uint8
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type SessionRequest
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SessionRequest struct {
|
||||||
|
XContent []byte // 32-byte X value
|
||||||
|
|
||||||
|
Padding []byte // padding of message 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*SessionRequest) Payload
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (sr *SessionRequest) Payload() []byte
|
||||||
|
```
|
||||||
|
Payload returns the message payload
|
||||||
|
|
||||||
|
#### func (*SessionRequest) PayloadSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (sr *SessionRequest) PayloadSize() int
|
||||||
|
```
|
||||||
|
PayloadSize returns the message payload size
|
||||||
|
|
||||||
|
#### func (*SessionRequest) Type
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (sr *SessionRequest) Type() MessageType
|
||||||
|
```
|
||||||
|
Type returns the message type
|
@@ -46,10 +46,12 @@ package ntcp
|
|||||||
|
|
||||||
type MessageType uint8
|
type MessageType uint8
|
||||||
|
|
||||||
const MessageTypeSessionRequest = 0x00
|
const (
|
||||||
const MessageTypeSessionCreated = 0x01
|
MessageTypeSessionRequest = 0x00
|
||||||
const MessageTypeSessionConfirmed = 0x02
|
MessageTypeSessionCreated = 0x01
|
||||||
const MessageTypeData = 0x03
|
MessageTypeSessionConfirmed = 0x02
|
||||||
|
MessageTypeData = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
type Message interface {
|
type Message interface {
|
||||||
// Type returns the message type
|
// Type returns the message type
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
package noise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/flynn/noise"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ComposeInitiatorHandshakeMessage(s noise.DHKey, rs []byte, payload []byte, ePrivate []byte) (negData, msg []byte, state *noise.HandshakeState, err error) {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *NoiseSession) RunClientHandshake() error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@@ -1,75 +0,0 @@
|
|||||||
package noise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *NoiseSession) Write(b []byte) (int, error) {
|
|
||||||
// interlock with Close below
|
|
||||||
for {
|
|
||||||
x := atomic.LoadInt32(&c.activeCall)
|
|
||||||
if x&1 != 0 {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"at": "(NoiseSession) Write",
|
|
||||||
"reason": "session is closed",
|
|
||||||
}).Error("session is closed")
|
|
||||||
return 0, errors.New("session is closed")
|
|
||||||
}
|
|
||||||
if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
|
|
||||||
defer atomic.AddInt32(&c.activeCall, -2)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := c.RunClientHandshake(); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
c.Mutex.Lock()
|
|
||||||
defer c.Mutex.Unlock()
|
|
||||||
if !c.handshakeComplete {
|
|
||||||
return 0, errors.New("internal error")
|
|
||||||
}
|
|
||||||
n, err := c.writePacketLocked(b)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *NoiseSession) writePacketLocked(data []byte) (int, error) {
|
|
||||||
var n int
|
|
||||||
if len(data) == 0 { //special case to answer when everything is ok during handshake
|
|
||||||
if _, err := c.Conn.Write(make([]byte, 2)); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for len(data) > 0 {
|
|
||||||
/*m := len(data)
|
|
||||||
packet := c.InitializePacket()
|
|
||||||
maxPayloadSize := c.maxPayloadSizeForWrite(packet)
|
|
||||||
if m > int(maxPayloadSize) {
|
|
||||||
m = int(maxPayloadSize)
|
|
||||||
}
|
|
||||||
if c.CipherState != nil {
|
|
||||||
////fmt.Println("writing encrypted packet:", m)
|
|
||||||
packet.reserve(uint16Size + uint16Size + m + macSize)
|
|
||||||
packet.resize(uint16Size + uint16Size + m)
|
|
||||||
copy(packet.data[uint16Size+uint16Size:], data[:m])
|
|
||||||
binary.BigEndian.PutUint16(packet.data[uint16Size:], uint16(m))
|
|
||||||
//fmt.Println("encrypt size", uint16(m))
|
|
||||||
} else {
|
|
||||||
packet.resize(len(packet.data) + len(data))
|
|
||||||
copy(packet.data[uint16Size:len(packet.data)], data[:m])
|
|
||||||
binary.BigEndian.PutUint16(packet.data, uint16(len(data)))
|
|
||||||
}
|
|
||||||
b := c.encryptIfNeeded(packet)
|
|
||||||
c.freeBlock(packet)
|
|
||||||
////fmt.Println(hex.EncodeToString(b))
|
|
||||||
if _, err := c.conn.Write(b); err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
n += m
|
|
||||||
data = data[m:]
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
270
lib/transport/noise/doc.md
Normal file
270
lib/transport/noise/doc.md
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
# noise
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/transport/noise"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const FlushLimit = 640 * 1024
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Noise
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Noise struct {
|
||||||
|
noise.Config
|
||||||
|
router_address.RouterAddress // always the local addr
|
||||||
|
*noise.HandshakeState
|
||||||
|
sync.Mutex
|
||||||
|
|
||||||
|
HandshakeStateResponsibility bool
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
wrapper around flynn/noise with just enough options exposed to enable
|
||||||
|
configuring NTCP2 possible and/or relatively intuitive
|
||||||
|
|
||||||
|
#### func NewNoise
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewNoise(ra router_address.RouterAddress) (ns *Noise, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Noise) Addr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *Noise) Addr() net.Addr
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Noise) DialNoise
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *Noise) DialNoise(addr router_address.RouterAddress) (conn net.Conn, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Noise) ListenNoise
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *Noise) ListenNoise() (list NoiseListener, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*Noise) LocalAddr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *Noise) LocalAddr() net.Addr
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type NoiseConn
|
||||||
|
|
||||||
|
```go
|
||||||
|
type NoiseConn struct {
|
||||||
|
*Noise
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*NoiseConn) Close
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) Close() error
|
||||||
|
```
|
||||||
|
Close implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) Frame
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) Frame(header, body []byte) (err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*NoiseConn) HandshakeStateCreate
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) HandshakeStateCreate(out, payload []byte) (by []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*NoiseConn) HandshakeStateRead
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) HandshakeStateRead() (err error)
|
||||||
|
```
|
||||||
|
HandshakeStateRead reads a handshake's state off the socket for storage in the
|
||||||
|
NoiseConn.HandshakeState
|
||||||
|
|
||||||
|
#### func (*NoiseConn) LocalAddr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) LocalAddr() net.Addr
|
||||||
|
```
|
||||||
|
LocalAddr implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) Read
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) Read(b []byte) (n int, err error)
|
||||||
|
```
|
||||||
|
Read implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) ReadMsg
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) ReadMsg(b []byte) (by []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*NoiseConn) RemoteAddr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) RemoteAddr() net.Addr
|
||||||
|
```
|
||||||
|
RemoteAddr implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) SetCipherStates
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) SetCipherStates(cs1, cs2 *noise.CipherState)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (*NoiseConn) SetDeadline
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) SetDeadline(t time.Time) error
|
||||||
|
```
|
||||||
|
SetDeadline implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) SetReadDeadline
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) SetReadDeadline(t time.Time) error
|
||||||
|
```
|
||||||
|
SetReadDeadline implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) SetWriteDeadline
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) SetWriteDeadline(t time.Time) error
|
||||||
|
```
|
||||||
|
SetWriteDeadline implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoiseConn) Write
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (nc *NoiseConn) Write(b []byte) (n int, err error)
|
||||||
|
```
|
||||||
|
Write implements net.Conn.
|
||||||
|
|
||||||
|
#### type NoiseListener
|
||||||
|
|
||||||
|
```go
|
||||||
|
type NoiseListener struct {
|
||||||
|
*Noise
|
||||||
|
net.Listener
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*NoiseListener) Accept
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *NoiseListener) Accept() (net.Conn, error)
|
||||||
|
```
|
||||||
|
Accept implements net.Listener.
|
||||||
|
|
||||||
|
#### func (*NoiseListener) Addr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *NoiseListener) Addr() net.Addr
|
||||||
|
```
|
||||||
|
Addr implements net.Listener.
|
||||||
|
|
||||||
|
#### func (*NoiseListener) Close
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (ns *NoiseListener) Close() error
|
||||||
|
```
|
||||||
|
Close implements net.Listener.
|
||||||
|
|
||||||
|
#### type NoisePacketConn
|
||||||
|
|
||||||
|
```go
|
||||||
|
type NoisePacketConn struct {
|
||||||
|
*Noise
|
||||||
|
// this is always a actually a PacketConn
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) Close
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (n *NoisePacketConn) Close() error
|
||||||
|
```
|
||||||
|
Close implements net.PacketConn. Subtle: this method shadows the method
|
||||||
|
(Conn).Close of NoisePacketConn.Conn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) LocalAddr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (n *NoisePacketConn) LocalAddr() net.Addr
|
||||||
|
```
|
||||||
|
LocalAddr implements net.PacketConn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) Read
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (*NoisePacketConn) Read(b []byte) (n int, err error)
|
||||||
|
```
|
||||||
|
Read implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) ReadFrom
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (*NoisePacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
||||||
|
```
|
||||||
|
ReadFrom implements net.PacketConn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) RemoteAddr
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (n *NoisePacketConn) RemoteAddr() net.Addr
|
||||||
|
```
|
||||||
|
RemoteAddr implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) SetDeadline
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (n *NoisePacketConn) SetDeadline(t time.Time) error
|
||||||
|
```
|
||||||
|
SetDeadline implements net.PacketConn. Subtle: this method shadows the method
|
||||||
|
(PacketConn).SetDeadline of NoisePacketConn.PacketConn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) SetReadDeadline
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (n *NoisePacketConn) SetReadDeadline(t time.Time) error
|
||||||
|
```
|
||||||
|
SetReadDeadline implements net.PacketConn. Subtle: this method shadows the
|
||||||
|
method (PacketConn).SetReadDeadline of NoisePacketConn.PacketConn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) SetWriteDeadline
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (n *NoisePacketConn) SetWriteDeadline(t time.Time) error
|
||||||
|
```
|
||||||
|
SetWriteDeadline implements net.PacketConn. Subtle: this method shadows the
|
||||||
|
method (PacketConn).SetWriteDeadline of NoisePacketConn.PacketConn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) Write
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (*NoisePacketConn) Write(b []byte) (n int, err error)
|
||||||
|
```
|
||||||
|
Write implements net.Conn.
|
||||||
|
|
||||||
|
#### func (*NoisePacketConn) WriteTo
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (*NoisePacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error)
|
||||||
|
```
|
||||||
|
WriteTo implements net.PacketConn.
|
@@ -1,41 +0,0 @@
|
|||||||
package noise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *NoiseTransport) Handshake(routerInfo router_info.RouterInfo) error {
|
|
||||||
c.Mutex.Lock()
|
|
||||||
defer c.Mutex.Unlock()
|
|
||||||
session, err := c.GetSession(routerInfo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
if session.(*NoiseSession).handshakeComplete {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if session.(*NoiseSession).Cond == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
session.(*NoiseSession).Cond.Wait()
|
|
||||||
}
|
|
||||||
// Set handshakeCond to indicate that this goroutine is committing to
|
|
||||||
// running the handshake.
|
|
||||||
session.(*NoiseSession).Cond = sync.NewCond(&c.Mutex)
|
|
||||||
c.Mutex.Unlock()
|
|
||||||
session.(*NoiseSession).Mutex.Lock()
|
|
||||||
defer session.(*NoiseSession).Mutex.Unlock()
|
|
||||||
c.Mutex.Lock()
|
|
||||||
// if c.config.isClient {
|
|
||||||
if err := session.(*NoiseSession).RunClientHandshake(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Wake any other goroutines that are waiting for this handshake to
|
|
||||||
// complete.
|
|
||||||
session.(*NoiseSession).Cond.Broadcast()
|
|
||||||
session.(*NoiseSession).Cond = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
154
lib/transport/noise/noise.go
Normal file
154
lib/transport/noise/noise.go
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/flynn/noise"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||||
|
)
|
||||||
|
|
||||||
|
// wrapper around flynn/noise with just enough options exposed to enable configuring NTCP2
|
||||||
|
// possible and/or relatively intuitive
|
||||||
|
type Noise struct {
|
||||||
|
noise.Config
|
||||||
|
router_info.RouterInfo // always the local
|
||||||
|
*noise.HandshakeState
|
||||||
|
|
||||||
|
HandshakeStateResponsibility bool
|
||||||
|
handshakeHash []byte
|
||||||
|
|
||||||
|
send, recv *noise.CipherState
|
||||||
|
|
||||||
|
readMsgBuf []byte
|
||||||
|
writeMsgBuf []byte
|
||||||
|
readBuf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ex_ns net.Conn = &NoiseConn{}
|
||||||
|
ex_ns_l net.Listener = &NoiseListener{}
|
||||||
|
ex_ns_u net.PacketConn = &NoisePacketConn{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewNoise creates a new Noise-based transport with only the config for our side of the connection.
|
||||||
|
// It accepts a RouterInfo which should always be our own RouterInfo.
|
||||||
|
func NewNoise(ri router_info.RouterInfo) (ns *Noise, err error) {
|
||||||
|
ns = &Noise{}
|
||||||
|
ns.RouterInfo = ri
|
||||||
|
// sk, err := ra.StaticKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ns.Config = noise.Config{
|
||||||
|
CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256),
|
||||||
|
Pattern: noise.HandshakeXK,
|
||||||
|
// StaticKeypair: ,
|
||||||
|
// StaticKeypair: ,
|
||||||
|
// EphemeralKeypair: ,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *Noise) LocalAddr() net.Addr {
|
||||||
|
return &ns.RouterInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *Noise) Addr() net.Addr {
|
||||||
|
return ns.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchAddr finds a transport suitable for an incoming RouterAddress
|
||||||
|
func (ns *Noise) MatchAddr(addr net.Addr) (*router_address.RouterAddress, error) {
|
||||||
|
for index, address := range ns.RouterInfo.RouterAddresses() {
|
||||||
|
log.Println("index", index, "address", address)
|
||||||
|
if addr.Network() == address.Network() {
|
||||||
|
return address, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no suitable address found for type %s from %s", addr.Network(), addr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func dialWrapper(network, address string) (net.Conn, error) {
|
||||||
|
switch network {
|
||||||
|
case "SSU24":
|
||||||
|
return net.Dial("udp4", address)
|
||||||
|
case "SSU26":
|
||||||
|
return net.Dial("udp6", address)
|
||||||
|
case "NTCP2":
|
||||||
|
return net.Dial("tcp", address)
|
||||||
|
case "NTCP24":
|
||||||
|
return net.Dial("tcp4", address)
|
||||||
|
case "NTCP26":
|
||||||
|
return net.Dial("tcp6", address)
|
||||||
|
case "NTCP4":
|
||||||
|
return net.Dial("tcp4", address)
|
||||||
|
case "NTCP6":
|
||||||
|
return net.Dial("tcp6", address)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown transport, cannot dial %s", network)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns Noise) DialNoise(addr router_address.RouterAddress) (net.Conn, error) {
|
||||||
|
cfg := ns
|
||||||
|
cfg.Initiator = false
|
||||||
|
network := addr.Network()
|
||||||
|
host, err := addr.Host()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("host error: %s", err)
|
||||||
|
}
|
||||||
|
port, err := addr.Port()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("port error: %s", err)
|
||||||
|
}
|
||||||
|
raddr := net.JoinHostPort(host.String(), port)
|
||||||
|
var netConn net.Conn
|
||||||
|
netConn, err = dialWrapper(network, raddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("dial error: %s", err)
|
||||||
|
}
|
||||||
|
cfg.HandshakeState, err = noise.NewHandshakeState(cfg.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("handshake state initialization error: %s", err)
|
||||||
|
}
|
||||||
|
laddr, err := ns.MatchAddr(&addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("transport mismatch error %s", err)
|
||||||
|
}
|
||||||
|
// cfg.Config.PeerEphemeral, err = AESDeObfuscateEphemeralKeys()
|
||||||
|
return &NoiseConn{
|
||||||
|
Noise: cfg,
|
||||||
|
Conn: netConn,
|
||||||
|
raddr: addr,
|
||||||
|
laddr: *laddr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns Noise) ListenNoise(addr router_address.RouterAddress) (list NoiseListener, err error) {
|
||||||
|
cfg := ns
|
||||||
|
cfg.Initiator = false
|
||||||
|
network := "tcp"
|
||||||
|
host, err := addr.Host()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
port, err := addr.Port()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
portNum, _ := strconv.Atoi(port)
|
||||||
|
port = strconv.Itoa(portNum + 1)
|
||||||
|
hostip := net.JoinHostPort(host.String(), port)
|
||||||
|
listener, err := net.Listen(network, hostip)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return NoiseListener{
|
||||||
|
Noise: cfg,
|
||||||
|
Listener: listener,
|
||||||
|
}, nil
|
||||||
|
}
|
138
lib/transport/noise/noise_conn.go
Normal file
138
lib/transport/noise/noise_conn.go
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/flynn/noise"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FlushLimit = 640 * 1024
|
||||||
|
|
||||||
|
type NoiseConn struct {
|
||||||
|
Noise
|
||||||
|
net.Conn
|
||||||
|
sync.Mutex
|
||||||
|
laddr, raddr router_address.RouterAddress
|
||||||
|
lock bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *NoiseConn) unlockMutex() {
|
||||||
|
if ns.lock {
|
||||||
|
ns.lock = false
|
||||||
|
ns.Mutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *NoiseConn) lockMutex() {
|
||||||
|
if !ns.lock {
|
||||||
|
ns.lock = true
|
||||||
|
ns.Mutex.Lock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements net.Conn.
|
||||||
|
func (nc *NoiseConn) Close() error {
|
||||||
|
return nc.Conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalAddr implements net.Conn.
|
||||||
|
func (nc *NoiseConn) LocalAddr() net.Addr {
|
||||||
|
return &nc.laddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements net.Conn.
|
||||||
|
func (nc *NoiseConn) Write(b []byte) (n int, err error) {
|
||||||
|
nc.lockMutex()
|
||||||
|
if nc.HandshakeState != nil {
|
||||||
|
defer nc.unlockMutex()
|
||||||
|
for nc.HandshakeState != nil && len(b) > 0 {
|
||||||
|
if !nc.Initiator {
|
||||||
|
// If we're the initiator, then we set that in advance and we already know.
|
||||||
|
// If not, we need to read the handshake state first.
|
||||||
|
err = nc.HandshakeStateRead()
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the HandshakeState is not populated here we are the initiator.
|
||||||
|
// we could(should? shouldn't?) check both but for now I'm sticking with what
|
||||||
|
// NoiseConn does
|
||||||
|
if nc.HandshakeState != nil {
|
||||||
|
// choose either the length of b or the maximum length of a message
|
||||||
|
l := min(noise.MaxMsgLen, len(b))
|
||||||
|
// update the HandshakeState using l number of bytes to the write message buffer
|
||||||
|
nc.writeMsgBuf, err = nc.HandshakeStateCreate(nc.writeMsgBuf[:0], b[:l])
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
// write the message buffer to the socket
|
||||||
|
_, err = nc.Conn.Write(nc.writeMsgBuf)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
n += l
|
||||||
|
b = b[l:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nc.unlockMutex()
|
||||||
|
// zero-out the write buffer
|
||||||
|
nc.writeMsgBuf = nc.writeMsgBuf[:0]
|
||||||
|
for len(b) > 0 {
|
||||||
|
outlen := len(nc.writeMsgBuf)
|
||||||
|
l := min(noise.MaxMsgLen, len(b))
|
||||||
|
nc.writeMsgBuf, err = nc.send.Encrypt(append(nc.writeMsgBuf, make([]byte, 4)...), nil, b[:l])
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
err = nc.Frame(nc.writeMsgBuf[outlen:], nc.writeMsgBuf[outlen+4:])
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
n += l
|
||||||
|
b = b[l:]
|
||||||
|
if len(nc.writeMsgBuf) > FlushLimit {
|
||||||
|
_, err = nc.Conn.Write(nc.writeMsgBuf)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
nc.writeMsgBuf = nc.writeMsgBuf[:0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(nc.writeMsgBuf) > 0 {
|
||||||
|
_, err = nc.Conn.Write(nc.writeMsgBuf)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
nc.writeMsgBuf = nc.writeMsgBuf[:0]
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read implements net.Conn.
|
||||||
|
func (nc *NoiseConn) Read(b []byte) (n int, err error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoteAddr implements net.Conn.
|
||||||
|
func (nc *NoiseConn) RemoteAddr() net.Addr {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDeadline implements net.Conn.
|
||||||
|
func (nc *NoiseConn) SetDeadline(t time.Time) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReadDeadline implements net.Conn.
|
||||||
|
func (nc *NoiseConn) SetReadDeadline(t time.Time) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriteDeadline implements net.Conn.
|
||||||
|
func (nc *NoiseConn) SetWriteDeadline(t time.Time) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
63
lib/transport/noise/noise_conn_util.go
Normal file
63
lib/transport/noise/noise_conn_util.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import "github.com/flynn/noise"
|
||||||
|
|
||||||
|
// HandshakeStateRead reads a handshake's state off the socket for storage in the
|
||||||
|
// NoiseConn.HandshakeState
|
||||||
|
func (nc *NoiseConn) HandshakeStateRead() (err error) {
|
||||||
|
nc.readMsgBuf, err = nc.ReadMsg(nc.readMsgBuf[:0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var cs1, cs2 *noise.CipherState
|
||||||
|
nc.readBuf, cs1, cs2, err = nc.HandshakeState.ReadMessage(nc.readBuf, nc.readMsgBuf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nc.SetCipherStates(cs1, cs2)
|
||||||
|
nc.HandshakeStateResponsibility = true
|
||||||
|
//if nc.rfmValidate != nil {
|
||||||
|
//err = nc.rfmValidate(nc.Conn.RemoteAddr(), nc.readMsgBuf)
|
||||||
|
//nc.rfmValidate = nil
|
||||||
|
//return err
|
||||||
|
//}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *NoiseConn) HandshakeStateCreate(out, payload []byte) (by []byte, err error) {
|
||||||
|
var cs1, cs2 *noise.CipherState
|
||||||
|
outlen := len(out)
|
||||||
|
out, cs1, cs2, err = nc.HandshakeState.WriteMessage(append(out, make([]byte, 4)...), payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//if nc.rfmValidate != nil {
|
||||||
|
// only applies to responders, not initiators.
|
||||||
|
//nc.rfmValidate = nil
|
||||||
|
//}
|
||||||
|
nc.SetCipherStates(cs1, cs2)
|
||||||
|
nc.HandshakeStateResponsibility = false
|
||||||
|
// nc.readBarrier.Release()
|
||||||
|
return out, nc.Frame(out[outlen:], out[outlen+4:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *NoiseConn) Frame(header, body []byte) (err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *NoiseConn) ReadMsg(b []byte) (by []byte, err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nc *NoiseConn) SetCipherStates(cs1, cs2 *noise.CipherState) {
|
||||||
|
if nc.Initiator {
|
||||||
|
nc.send, nc.recv = cs1, cs2
|
||||||
|
} else {
|
||||||
|
nc.send, nc.recv = cs2, cs1
|
||||||
|
}
|
||||||
|
if nc.send != nil {
|
||||||
|
// nc.readBarrier.Release()
|
||||||
|
nc.handshakeHash = nc.HandshakeState.ChannelBinding()
|
||||||
|
nc.HandshakeState = nil
|
||||||
|
}
|
||||||
|
}
|
44
lib/transport/noise/noise_listener.go
Normal file
44
lib/transport/noise/noise_listener.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/flynn/noise"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NoiseListener struct {
|
||||||
|
Noise
|
||||||
|
net.Listener
|
||||||
|
sync.Mutex
|
||||||
|
lock bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addr implements net.Listener.
|
||||||
|
func (ns *NoiseListener) Addr() net.Addr {
|
||||||
|
return ns.Noise.Addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements net.Listener.
|
||||||
|
func (ns *NoiseListener) Close() error {
|
||||||
|
return ns.Listener.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept implements net.Listener.
|
||||||
|
func (ns *NoiseListener) Accept() (net.Conn, error) {
|
||||||
|
cfg := ns.Noise
|
||||||
|
cfg.Initiator = false
|
||||||
|
accept, err := ns.Listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hs, err := noise.NewHandshakeState(ns.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfg.HandshakeState = hs
|
||||||
|
return &NoiseConn{
|
||||||
|
Noise: cfg,
|
||||||
|
Conn: accept,
|
||||||
|
}, nil
|
||||||
|
}
|
40
lib/transport/noise/noise_obfs.go
Normal file
40
lib/transport/noise/noise_obfs.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"encoding/hex"
|
||||||
|
|
||||||
|
"github.com/flynn/noise"
|
||||||
|
"github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Noise obfuscation functions used in I2P NTCP2 and SSU2 Handshakes,
|
||||||
|
// including obfuscating the ephemeral keys with a known key and IV found
|
||||||
|
// in the netDb.
|
||||||
|
func AESDeObfuscateEphemeralKeys(cipherText string, config noise.Config, bob router_address.RouterAddress) ([]byte, error) {
|
||||||
|
bobsStaticKey, err := bob.StaticKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bobsInitializatonVector, err := bob.InitializationVector()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.WithFields(
|
||||||
|
log.Fields{
|
||||||
|
"at": "(noise) AESObfuscateEphemeralKeys",
|
||||||
|
}).Debugf("getting ready to deobfuscate our bob's ephemeral keys with bob's static key %s and IV %s", bobsStaticKey, bobsInitializatonVector)
|
||||||
|
deobfuscate, err := hex.DecodeString(cipherText)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
block, err := aes.NewCipher(bobsStaticKey[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mode := cipher.NewCBCDecrypter(block, bobsInitializatonVector[:])
|
||||||
|
mode.CryptBlocks([]byte(deobfuscate), []byte(deobfuscate))
|
||||||
|
return deobfuscate, nil
|
||||||
|
}
|
66
lib/transport/noise/noise_packetconn.go
Normal file
66
lib/transport/noise/noise_packetconn.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NoisePacketConn struct {
|
||||||
|
*Noise
|
||||||
|
// this is always a actually a PacketConn
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read implements net.Conn.
|
||||||
|
func (*NoisePacketConn) Read(b []byte) (n int, err error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoteAddr implements net.Conn.
|
||||||
|
func (n *NoisePacketConn) RemoteAddr() net.Addr {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements net.Conn.
|
||||||
|
func (*NoisePacketConn) Write(b []byte) (n int, err error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements net.PacketConn.
|
||||||
|
// Subtle: this method shadows the method (Conn).Close of NoisePacketConn.Conn.
|
||||||
|
func (n *NoisePacketConn) Close() error {
|
||||||
|
return n.Conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalAddr implements net.PacketConn.
|
||||||
|
func (n *NoisePacketConn) LocalAddr() net.Addr {
|
||||||
|
return &n.Noise.RouterInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadFrom implements net.PacketConn.
|
||||||
|
func (*NoisePacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDeadline implements net.PacketConn.
|
||||||
|
// Subtle: this method shadows the method (PacketConn).SetDeadline of NoisePacketConn.PacketConn.
|
||||||
|
func (n *NoisePacketConn) SetDeadline(t time.Time) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReadDeadline implements net.PacketConn.
|
||||||
|
// Subtle: this method shadows the method (PacketConn).SetReadDeadline of NoisePacketConn.PacketConn.
|
||||||
|
func (n *NoisePacketConn) SetReadDeadline(t time.Time) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWriteDeadline implements net.PacketConn.
|
||||||
|
// Subtle: this method shadows the method (PacketConn).SetWriteDeadline of NoisePacketConn.PacketConn.
|
||||||
|
func (n *NoisePacketConn) SetWriteDeadline(t time.Time) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo implements net.PacketConn.
|
||||||
|
func (*NoisePacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
13
lib/transport/noise/noise_test.go
Normal file
13
lib/transport/noise/noise_test.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServer(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEstablishment(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
@@ -1,85 +0,0 @@
|
|||||||
package noise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
cb "github.com/emirpasic/gods/queues/circularbuffer"
|
|
||||||
"github.com/flynn/noise"
|
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
|
||||||
"github.com/go-i2p/go-i2p/lib/i2np"
|
|
||||||
"github.com/go-i2p/go-i2p/lib/transport"
|
|
||||||
)
|
|
||||||
|
|
||||||
type NoiseSession struct {
|
|
||||||
*cb.Queue
|
|
||||||
router_info.RouterInfo
|
|
||||||
*noise.CipherState
|
|
||||||
sync.Mutex
|
|
||||||
*sync.Cond
|
|
||||||
*NoiseTransport
|
|
||||||
handshakeBuffer bytes.Buffer
|
|
||||||
activeCall int32
|
|
||||||
handshakeComplete bool
|
|
||||||
Conn net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read implements net.Conn
|
|
||||||
func (*NoiseSession) Read(b []byte) (n int, err error) {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoteAddr implements net.Conn
|
|
||||||
func (*NoiseSession) RemoteAddr() net.Addr {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDeadline implements net.Conn
|
|
||||||
func (*NoiseSession) SetDeadline(t time.Time) error {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetReadDeadline implements net.Conn
|
|
||||||
func (*NoiseSession) SetReadDeadline(t time.Time) error {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetWriteDeadline implements net.Conn
|
|
||||||
func (*NoiseSession) SetWriteDeadline(t time.Time) error {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
var exampleNoiseSession transport.TransportSession = &NoiseSession{}
|
|
||||||
var ExampleNoiseSession net.Conn = exampleNoiseSession.(*NoiseSession)
|
|
||||||
|
|
||||||
func (s *NoiseSession) LocalAddr() net.Addr {
|
|
||||||
return s.Conn.LocalAddr()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *NoiseSession) QueueSendI2NP(msg i2np.I2NPMessage) {
|
|
||||||
s.Queue.Enqueue(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *NoiseSession) SendQueueSize() int {
|
|
||||||
return s.Queue.Size()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *NoiseSession) ReadNextI2NP() (i2np.I2NPMessage, error) {
|
|
||||||
return i2np.I2NPMessage{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *NoiseSession) Close() error {
|
|
||||||
s.Queue.Clear()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNoiseTransportSession(ri router_info.RouterInfo, socket net.Conn) (transport.TransportSession, error) {
|
|
||||||
return &NoiseSession{
|
|
||||||
Queue: cb.New(1024),
|
|
||||||
RouterInfo: ri,
|
|
||||||
Conn: socket,
|
|
||||||
}, nil
|
|
||||||
}
|
|
@@ -1,96 +0,0 @@
|
|||||||
package noise
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NoiseTransport is an unused transport which is used only for testing the
|
|
||||||
* transport interfaces. I2P adds obfuscation to NOISE with the NTCP2 protocol
|
|
||||||
* which is one of the transports which we use in practice.
|
|
||||||
**/
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/flynn/noise"
|
|
||||||
"github.com/go-i2p/go-i2p/lib/common/data"
|
|
||||||
"github.com/go-i2p/go-i2p/lib/common/router_identity"
|
|
||||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
|
||||||
"github.com/go-i2p/go-i2p/lib/transport"
|
|
||||||
)
|
|
||||||
|
|
||||||
type NoiseTransport struct {
|
|
||||||
*noise.CipherState
|
|
||||||
router_identity.RouterIdentity
|
|
||||||
sync.Mutex
|
|
||||||
Listener net.Listener
|
|
||||||
peerConnections map[data.Hash]transport.TransportSession
|
|
||||||
}
|
|
||||||
|
|
||||||
var exampleNoiseTransport transport.Transport = &NoiseTransport{}
|
|
||||||
|
|
||||||
// ExampleNoiseListener is not a real Noise Listener, do not use it.
|
|
||||||
// It is exported so that it can be confirmed that the transport
|
|
||||||
// implements net.Listener
|
|
||||||
var ExampleNoiseListener net.Listener = exampleNoiseTransport
|
|
||||||
|
|
||||||
func (noopt *NoiseTransport) Accept() (net.Conn, error) {
|
|
||||||
return noopt.Listener.Accept()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (noopt *NoiseTransport) Addr() net.Addr {
|
|
||||||
return noopt.Listener.Addr()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (noopt *NoiseTransport) Name() string {
|
|
||||||
return "noise"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the router identity for this transport.
|
|
||||||
// will bind if the underlying socket is not already
|
|
||||||
// if the underlying socket is already bound update the RouterIdentity
|
|
||||||
// returns any errors that happen if they do
|
|
||||||
func (noopt *NoiseTransport) SetIdentity(ident router_identity.RouterIdentity) error {
|
|
||||||
noopt.RouterIdentity = ident
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain a transport session with a router given its RouterInfo.
|
|
||||||
// If a session with this router is NOT already made attempt to create one and block until made or until an error happens
|
|
||||||
// returns an established TransportSession and nil on success
|
|
||||||
// returns nil and an error on error
|
|
||||||
func (noopt *NoiseTransport) GetSession(routerInfo router_info.RouterInfo) (transport.TransportSession, error) {
|
|
||||||
hash := routerInfo.IdentHash()
|
|
||||||
if len(hash) == 0 {
|
|
||||||
return nil, errors.New("NoiseTransport: GetSession: RouterInfo has no IdentityHash")
|
|
||||||
}
|
|
||||||
if t, ok := noopt.peerConnections[hash]; ok == true {
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
conn, err := noopt.Accept()
|
|
||||||
if err == nil {
|
|
||||||
if noopt.peerConnections[hash], err = NewNoiseTransportSession(routerInfo, conn); err != nil {
|
|
||||||
return noopt.peerConnections[hash], err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if a routerInfo is compatable with this transport
|
|
||||||
func (noopt *NoiseTransport) Compatable(routerInfo router_info.RouterInfo) bool {
|
|
||||||
_, ok := noopt.peerConnections[routerInfo.IdentHash()]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// close the transport cleanly
|
|
||||||
// blocks until done
|
|
||||||
// returns an error if one happens
|
|
||||||
func (noopt *NoiseTransport) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNoiseTransport(netSocket net.Listener) *NoiseTransport {
|
|
||||||
return &NoiseTransport{
|
|
||||||
peerConnections: make(map[data.Hash]transport.TransportSession),
|
|
||||||
Listener: netSocket,
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
package noise
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTransport(t *testing.T) {
|
|
||||||
ln, err := net.Listen("tcp", ":42069")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
nt := NewNoiseTransport(ln)
|
|
||||||
|
|
||||||
t.Log(nt.Name())
|
|
||||||
}
|
|
30
lib/transport/ntcp/doc.md
Normal file
30
lib/transport/ntcp/doc.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# ntcp
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/transport/ntcp"
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
NTCP_PROTOCOL_VERSION = 2
|
||||||
|
NTCP_PROTOCOL_NAME = "NTCP2"
|
||||||
|
NTCP_MESSAGE_MAX_SIZE = 65537
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Session
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Session struct{}
|
||||||
|
```
|
||||||
|
|
||||||
|
Session implements TransportSession An established transport session
|
||||||
|
|
||||||
|
#### type Transport
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Transport struct{}
|
||||||
|
```
|
||||||
|
|
||||||
|
Transport is an ntcp transport implementing transport.Transport interface
|
@@ -2,5 +2,4 @@ package ntcp
|
|||||||
|
|
||||||
// Session implements TransportSession
|
// Session implements TransportSession
|
||||||
// An established transport session
|
// An established transport session
|
||||||
type Session struct {
|
type Session struct{}
|
||||||
}
|
|
||||||
|
@@ -11,5 +11,4 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Transport is an ntcp transport implementing transport.Transport interface
|
// Transport is an ntcp transport implementing transport.Transport interface
|
||||||
type Transport struct {
|
type Transport struct{}
|
||||||
}
|
|
||||||
|
7
lib/transport/ssu/doc.md
Normal file
7
lib/transport/ssu/doc.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# ssu
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/transport/ssu"
|
||||||
|
|
||||||
|
i2p ssu transport implementation
|
||||||
|
|
||||||
|
## Usage
|
@@ -708,6 +708,7 @@ func maybeAppendDelay(di_flag DeliveryInstructions, data, current []byte) (now [
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func maybeAppendMessageID(di_flag DeliveryInstructions, di_type int, data, current []byte) (now []byte, err error) {
|
func maybeAppendMessageID(di_flag DeliveryInstructions, di_type int, data, current []byte) (now []byte, err error) {
|
||||||
if di_type == FIRST_FRAGMENT {
|
if di_type == FIRST_FRAGMENT {
|
||||||
if fragmented, _ := di_flag.Fragmented(); fragmented {
|
if fragmented, _ := di_flag.Fragmented(); fragmented {
|
||||||
|
259
lib/tunnel/doc.md
Normal file
259
lib/tunnel/doc.md
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
# tunnel
|
||||||
|
--
|
||||||
|
import "github.com/go-i2p/go-i2p/lib/tunnel"
|
||||||
|
|
||||||
|
i2p garlic tunnel implementation
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
DT_LOCAL = iota
|
||||||
|
DT_TUNNEL
|
||||||
|
DT_ROUTER
|
||||||
|
DT_UNUSED
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
FIRST_FRAGMENT = iota
|
||||||
|
FOLLOW_ON_FRAGMENT
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
FLAG_SIZE = 1
|
||||||
|
TUNNEL_ID_SIZE = 4
|
||||||
|
HASH_SIZE = 32
|
||||||
|
DELAY_SIZE = 1
|
||||||
|
MESSAGE_ID_SIZE = 4
|
||||||
|
EXTENDED_OPTIONS_MIN_SIZE = 2
|
||||||
|
SIZE_FIELD_SIZE = 2
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type DecryptedTunnelMessage
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DecryptedTunnelMessage [1028]byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (DecryptedTunnelMessage) Checksum
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (decrypted_tunnel_message DecryptedTunnelMessage) Checksum() crypto.TunnelIV
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (DecryptedTunnelMessage) DeliveryInstructionsWithFragments
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (decrypted_tunnel_message DecryptedTunnelMessage) DeliveryInstructionsWithFragments() []DeliveryInstructionsWithFragment
|
||||||
|
```
|
||||||
|
Returns a slice of DeliveryInstructionWithFragment structures, which all of the
|
||||||
|
Delivery Instructions in the tunnel message and their corresponding
|
||||||
|
MessageFragment structures.
|
||||||
|
|
||||||
|
#### func (DecryptedTunnelMessage) ID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (decrypted_tunnel_message DecryptedTunnelMessage) ID() TunnelID
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (DecryptedTunnelMessage) IV
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (decrypted_tunnel_message DecryptedTunnelMessage) IV() crypto.TunnelIV
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type DelayFactor
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DelayFactor byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type DeliveryInstructions
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DeliveryInstructions []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) Delay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) Delay() (delay_factor DelayFactor, err error)
|
||||||
|
```
|
||||||
|
Return the DelayFactor if present and any errors encountered parsing the
|
||||||
|
DeliveryInstructions.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) DeliveryType
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) DeliveryType() (byte, error)
|
||||||
|
```
|
||||||
|
Return the delivery type for these DeliveryInstructions, can be of type
|
||||||
|
DT_LOCAL, DT_TUNNEL, DT_ROUTER, or DT_UNUSED.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) ExtendedOptions
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) ExtendedOptions() (data []byte, err error)
|
||||||
|
```
|
||||||
|
Return the Extended Options data if present, or an error if not present.
|
||||||
|
Extended Options in unimplemented in the Java router and the presence of
|
||||||
|
extended options will generate a warning.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) FragmentNumber
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) FragmentNumber() (int, error)
|
||||||
|
```
|
||||||
|
Read the integer stored in the 6-1 bits of a FOLLOW_ON_FRAGMENT's flag,
|
||||||
|
indicating the fragment number.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) FragmentSize
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) FragmentSize() (frag_size uint16, err error)
|
||||||
|
```
|
||||||
|
Return the size of the associated I2NP fragment and an error if the data is
|
||||||
|
unavailable.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) Fragmented
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) Fragmented() (bool, error)
|
||||||
|
```
|
||||||
|
Returns true if the Delivery Instructions are fragmented or false if the
|
||||||
|
following data contains the entire message
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) HasDelay
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) HasDelay() (bool, error)
|
||||||
|
```
|
||||||
|
Check if the delay bit is set. This feature in unimplemented in the Java router.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) HasExtendedOptions
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) HasExtendedOptions() (bool, error)
|
||||||
|
```
|
||||||
|
Check if the extended options bit is set. This feature in unimplemented in the
|
||||||
|
Java router.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) HasHash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) HasHash() (bool, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) HasTunnelID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) HasTunnelID() (bool, error)
|
||||||
|
```
|
||||||
|
Check if the DeliveryInstructions is of type DT_TUNNEL.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) Hash
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) Hash() (hash common.Hash, err error)
|
||||||
|
```
|
||||||
|
Return the hash for these DeliveryInstructions, which varies by hash type.
|
||||||
|
|
||||||
|
If the type is DT_TUNNEL, hash is the SHA256 of the gateway router, if
|
||||||
|
the type is DT_ROUTER it is the SHA256 of the router.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) LastFollowOnFragment
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) LastFollowOnFragment() (bool, error)
|
||||||
|
```
|
||||||
|
Read the value of the 0 bit of a FOLLOW_ON_FRAGMENT, which is set to 1 to
|
||||||
|
indicate the last fragment.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) MessageID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) MessageID() (msgid uint32, err error)
|
||||||
|
```
|
||||||
|
Return the I2NP Message ID or 0 and an error if the data is not available for
|
||||||
|
this DeliveryInstructions.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) TunnelID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) TunnelID() (tunnel_id uint32, err error)
|
||||||
|
```
|
||||||
|
Return the tunnel ID in this DeliveryInstructions or 0 and an error if the
|
||||||
|
DeliveryInstructions are not of type DT_TUNNEL.
|
||||||
|
|
||||||
|
#### func (DeliveryInstructions) Type
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (delivery_instructions DeliveryInstructions) Type() (int, error)
|
||||||
|
```
|
||||||
|
Return if the DeliveryInstructions are of type FIRST_FRAGMENT or
|
||||||
|
FOLLOW_ON_FRAGMENT.
|
||||||
|
|
||||||
|
#### type DeliveryInstructionsWithFragment
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DeliveryInstructionsWithFragment struct {
|
||||||
|
DeliveryInstructions DeliveryInstructions
|
||||||
|
MessageFragment []byte
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type EncryptedTunnelMessage
|
||||||
|
|
||||||
|
```go
|
||||||
|
type EncryptedTunnelMessage crypto.TunnelData
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### func (EncryptedTunnelMessage) Data
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tm EncryptedTunnelMessage) Data() crypto.TunnelIV
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (EncryptedTunnelMessage) ID
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tm EncryptedTunnelMessage) ID() (tid TunnelID)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func (EncryptedTunnelMessage) IV
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (tm EncryptedTunnelMessage) IV() crypto.TunnelIV
|
||||||
|
```
|
||||||
|
|
||||||
|
#### type Participant
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Participant struct {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### type Pool
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Pool struct{}
|
||||||
|
```
|
||||||
|
|
||||||
|
a pool of tunnels which we have created
|
||||||
|
|
||||||
|
#### type TunnelID
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TunnelID uint32
|
||||||
|
```
|
@@ -2,6 +2,7 @@ package tunnel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user