mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-09-18 14:47:52 -04:00
Compare commits
24 Commits
noise-tran
...
0.0.11
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f144c457ba | ||
![]() |
ac705dee76 | ||
![]() |
ca0443ae6a | ||
![]() |
94d0d8efb7 | ||
![]() |
8176e126cb | ||
![]() |
992c5537db | ||
![]() |
5ff9f5578e | ||
![]() |
889ec939b3 | ||
![]() |
6e3a5923cd | ||
![]() |
ce25a2f0fb | ||
![]() |
ec22860bb5 | ||
![]() |
cefdcd8c14 | ||
![]() |
d519f7678d | ||
![]() |
8dfc5ee5b8 | ||
![]() |
d8317351cf | ||
![]() |
ef127d81c1 | ||
![]() |
8acfba160f | ||
![]() |
d93e78d772 | ||
![]() |
bdc9ca4c2b | ||
![]() |
83f3d11621 | ||
![]() |
784f72403b | ||
![]() |
664a17e42a | ||
![]() |
37718c36f8 | ||
![]() |
b0fcf4bc11 |
19
Makefile
19
Makefile
@@ -1,6 +1,8 @@
|
||||
RELEASE_TAG=0.0.1
|
||||
RELEASE_VERSION=${RELEASE_TAG}
|
||||
RELEASE_DESCRIPTION=`cat PASTA.md`
|
||||
REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
|
||||
ifdef GOROOT
|
||||
GO = $(GOROOT)/bin/go
|
||||
endif
|
||||
@@ -18,8 +20,19 @@ build: clean $(EXE)
|
||||
$(EXE):
|
||||
$(GO) build -v -o $(EXE)
|
||||
|
||||
test:
|
||||
$(GO) test -v -failfast ./lib/common/data/...
|
||||
test: fmt
|
||||
$(GO) test -vv -failfast ./lib/common/...
|
||||
|
||||
clean:
|
||||
$(GO) clean -v
|
||||
|
||||
fmt:
|
||||
find . -name '*.go' -exec gofmt -w -s {} \;
|
||||
|
||||
info:
|
||||
echo "GOROOT: ${GOROOT}"
|
||||
echo "GO: ${GO}"
|
||||
echo "REPO: ${REPO}"
|
||||
|
||||
release:
|
||||
github-release release -u go-i2p -r go-i2p -n "${RELEASE_VERSION}" -t "${RELEASE_TAG}" -d "${RELEASE_DESCRIPTION}" -p
|
||||
|
33
PASTA.md
33
PASTA.md
@@ -1,19 +1,18 @@
|
||||
Weekly notes about what I'm working on
|
||||
======================================
|
||||
At long last... something useful
|
||||
================================
|
||||
|
||||
July 18, 2022:
|
||||
It's been 2 years of me mostly not having time to work on go-i2p itself since my last update.
|
||||
However, after much waiting, this library is actually **useful** for something.
|
||||
It is now being used in the `reseed-tools` application to examine RouterInfos prior to including them in reseed bundles.
|
||||
Routers that self-report as unreachable or congested will be excluded from future reseed bundles.
|
||||
Additionally, routers that self-report an old version will be excluded from reseed bundles.
|
||||
This should help new users build better connections faster with the existing, working router implementations.
|
||||
|
||||
- Implementation-in-Progress of a pure-Noise TCP transport using flynn/noise.
|
||||
- This transport is **not** operable with the rest of the I2P network and useful
|
||||
only for testing the transport interface implementation.
|
||||
- Most examples/docs on flynn/noise use client-server paradigm and not P2P paradigm, strictly
|
||||
speaking.
|
||||
- It does *not* process messages for obfuscation or de-obfuscation, key difference from NTCP2
|
||||
- It doesn't yet actually manage sending messages on a socket, right now it can:
|
||||
- Set up a Transport muxer
|
||||
- Set up a Transport, which is basically a session muxer sharing a common socket
|
||||
- Set up a Session, which is an individual connection to a peer which speaks the transport protocol
|
||||
- At some point there needs to be a loop on the socket which reads the socket for input and output.
|
||||
- At this time the transports *intentionally* do not know about the nature of the underlying socket
|
||||
beyond the fact that it must implement a `net.Conn` interface so that it can connect over TCP.
|
||||
- In the future, this will need to be able to accept either a `net.Conn` or a `net.PacketConn`
|
||||
This is not a working release of a go-i2p router
|
||||
------------------------------------------------
|
||||
|
||||
It is a numbered version of the go-i2p library, which is pre-release, expressly for use in the `reseed-tools` application.
|
||||
The common library works, and so do some of the cryptographic primitives, however the API is unstable and the software itself is certain to have serious bugs outside of a few well-tested areas.
|
||||
If you're using it for something other than parsing and analyzing RouterInfos and LeaseSets, you'll probably encounter bugs.
|
||||
Please report them to the https://github.com/go-i2p/go-i2p
|
||||
Use any part of it at your own risk.
|
||||
|
23
README.md
23
README.md
@@ -51,8 +51,8 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- [ ] Message handling
|
||||
- NetDB
|
||||
- [ ] Local storage
|
||||
- [ ] Persistence to disk
|
||||
- [ ] Reseeding
|
||||
- [/] Persistence to disk
|
||||
- [X] Reseeding
|
||||
- [ ] Lookups
|
||||
- [ ] Expiry
|
||||
- [ ] Exploration
|
||||
@@ -60,12 +60,12 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- [ ] Floodfill
|
||||
- [ ] LS2 and Encrypted Leasesets
|
||||
- Transports
|
||||
- [ ] Transport manager
|
||||
- [X] Transport manager
|
||||
- NTCP2
|
||||
- [ ] Handshake
|
||||
- [ ] Session tracking
|
||||
- [ ] Automatic session creation
|
||||
- SSU
|
||||
- SSU2
|
||||
- [ ] Handshake
|
||||
- [ ] Session tracking
|
||||
- [ ] Automatic session creation
|
||||
@@ -78,7 +78,20 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- [ ] Participating
|
||||
- [ ] Tunnel Message Crypto
|
||||
- [ ] Tunnel Message Fragmentation/Reassembly
|
||||
|
||||
- Common Data Structures
|
||||
- [/] Keys and Cert
|
||||
- [X] Key Certificates
|
||||
- [X] Certificate
|
||||
- [X] Lease
|
||||
- [X] Lease Set
|
||||
- [X] Router Info
|
||||
- [X] Router Identity
|
||||
- [X] Router Address
|
||||
- [X] Session Key
|
||||
- [X] Signature Types
|
||||
- [X] Destination
|
||||
- [X] Data Types
|
||||
- [X] Session Tag
|
||||
|
||||
## Contributing
|
||||
|
||||
|
10
go.mod
10
go.mod
@@ -3,13 +3,9 @@ module github.com/go-i2p/go-i2p
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/dchest/siphash v1.2.3 // indirect
|
||||
github.com/emirpasic/gods v1.18.1
|
||||
github.com/flynn/noise v1.0.0
|
||||
github.com/go-noisesocket/noisesocket v0.0.0-20191014121341-f487ac765620
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/flynn/noise v1.1.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
|
||||
golang.org/x/crypto v0.23.0
|
||||
)
|
||||
|
60
go.sum
60
go.sum
@@ -1,43 +1,69 @@
|
||||
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
|
||||
github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
||||
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||
github.com/go-noisesocket/noisesocket v0.0.0-20191014121341-f487ac765620 h1:MjTFQi2DyJifqefRVjAs+P2gaoUAj2rcDpYX7ERggEA=
|
||||
github.com/go-noisesocket/noisesocket v0.0.0-20191014121341-f487ac765620/go.mod h1:y9SBFk2hEIPWY7Aj3bXG+K1xp8wWnQ6kVq2wsYSPByU=
|
||||
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/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
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/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
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=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
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-20210423082822-04245dca01da/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-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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-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.6/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-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 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
@@ -1,4 +1,2 @@
|
||||
//
|
||||
// provides generic interfaces for initial bootstrap into network and network reseeding
|
||||
//
|
||||
package bootstrap
|
||||
|
@@ -126,29 +126,19 @@ func NewCertificate(data []byte) (certificate *Certificate, err error) {
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": len(data),
|
||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
||||
}).Error("invalid certificate")
|
||||
err = fmt.Errorf("error parsing certificate: certificate is too short")
|
||||
}).Error("invalid certificate, empty")
|
||||
err = fmt.Errorf("error parsing certificate: certificate is empty")
|
||||
return
|
||||
case 1:
|
||||
certificate.kind = Integer(data[0:0])
|
||||
case 1 , 2:
|
||||
certificate.kind = Integer(data[0:len(data)-1])
|
||||
certificate.len = Integer([]byte{0})
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": len(data),
|
||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
||||
}).Error("invalid certificate")
|
||||
}).Error("invalid certificate, too short")
|
||||
err = fmt.Errorf("error parsing certificate: certificate is too short")
|
||||
return
|
||||
case 2:
|
||||
certificate.kind = Integer(data[0:1])
|
||||
certificate.len = Integer([]byte{0})
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": len(data),
|
||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
||||
}).Error("invalid certificate")
|
||||
err = fmt.Errorf("error parsing certificate length: certificate is too short")
|
||||
return
|
||||
default:
|
||||
certificate.kind = Integer(data[0:1])
|
||||
certificate.len = Integer(data[1:3])
|
||||
@@ -160,17 +150,11 @@ func NewCertificate(data []byte) (certificate *Certificate, err error) {
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": certificate.len.Int(),
|
||||
"certificate_payload_length": payleng,
|
||||
"data_bytes:": string(data),
|
||||
"kind_bytes": data[0:1],
|
||||
"len_bytes": data[1:3],
|
||||
"reason": err.Error(),
|
||||
}).Error("invalid certificate")
|
||||
return
|
||||
} else if certificate.len.Int() < len(data)-CERT_MIN_SIZE {
|
||||
err = fmt.Errorf("certificate parsing warning: certificate data is longer than specified by length")
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": certificate.len.Int(),
|
||||
"certificate_payload_length": payleng,
|
||||
"reason": err.Error(),
|
||||
}).Error("invalid certificate")
|
||||
}).Error("invalid certificate, shorter than specified by length")
|
||||
return
|
||||
}
|
||||
return
|
||||
@@ -182,8 +166,8 @@ func NewCertificate(data []byte) (certificate *Certificate, err error) {
|
||||
func ReadCertificate(data []byte) (certificate *Certificate, remainder []byte, err error) {
|
||||
certificate, err = NewCertificate(data)
|
||||
if err != nil && err.Error() == "certificate parsing warning: certificate data is longer than specified by length" {
|
||||
remainder = certificate.ExcessBytes()
|
||||
err = nil
|
||||
}
|
||||
remainder = certificate.ExcessBytes()
|
||||
return
|
||||
}
|
||||
|
@@ -50,7 +50,9 @@ func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err
|
||||
if size < MAX_INTEGER_SIZE {
|
||||
integerSize = size
|
||||
}
|
||||
i, remainder := ReadInteger(bytes, integerSize)
|
||||
intBytes := bytes[:integerSize]
|
||||
remainder = bytes[integerSize:]
|
||||
i, _ := ReadInteger(intBytes, integerSize)
|
||||
integer = &i
|
||||
return
|
||||
}
|
||||
|
@@ -126,28 +126,25 @@ func beginsWith(bytes []byte, chr byte) bool {
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error) {
|
||||
if len(bytes) == 0 {
|
||||
if len(bytes) < 3 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "ReadMapping",
|
||||
"reason": "zero length",
|
||||
}).Warn("mapping format violation")
|
||||
e := errors.New("zero length")
|
||||
err = append(err, e)
|
||||
return
|
||||
}
|
||||
size, remainder, e := NewInteger(bytes, 2)
|
||||
if e != nil {
|
||||
err = append(err, e)
|
||||
}
|
||||
|
||||
mapping.size = size
|
||||
if e != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "ReadMapping",
|
||||
"reason": "error parsing integer",
|
||||
}).Warn("mapping format violation")
|
||||
e := errors.New("error parsing integer")
|
||||
err = append(err, e)
|
||||
if size.Int() == 0 {
|
||||
return
|
||||
}
|
||||
mapping.size = size
|
||||
map_bytes := remainder[:mapping.size.Int()]
|
||||
remainder = remainder[mapping.size.Int():]
|
||||
if len(remainder) == 0 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "ReadMapping",
|
||||
@@ -156,7 +153,10 @@ func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error)
|
||||
e := errors.New("zero length")
|
||||
err = append(err, e)
|
||||
}
|
||||
vals, remainder, mappingValueErrs := ReadMappingValues(bytes)
|
||||
// TODO: this should take the remainder and the length we already parsed above, as a parameter.
|
||||
// Like tomorrow morning.
|
||||
// ReadMappingValues should not attempt to figure out the length of the bytes it's reading over.
|
||||
vals, _, mappingValueErrs := ReadMappingValues(map_bytes, *mapping.size)
|
||||
|
||||
err = append(err, mappingValueErrs...)
|
||||
mapping.vals = vals
|
||||
|
@@ -10,6 +10,17 @@ import (
|
||||
// MappingValues represents the parsed key value pairs inside of an I2P Mapping.
|
||||
type MappingValues [][2]I2PString
|
||||
|
||||
func (m MappingValues) Get(key I2PString) I2PString {
|
||||
keyBytes, _ := key.Data()
|
||||
for _, pair := range m {
|
||||
kb, _ := pair[0][0:].Data()
|
||||
if kb == keyBytes {
|
||||
return pair[1][1:]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValuesToMapping creates a *Mapping using MappingValues.
|
||||
// The values are sorted in the order defined in mappingOrder.
|
||||
func ValuesToMapping(values MappingValues) *Mapping {
|
||||
@@ -46,11 +57,11 @@ func mappingOrder(values MappingValues) {
|
||||
// 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 ReadMappingValues(remainder []byte) (values *MappingValues, remainder_bytes []byte, errs []error) {
|
||||
mapping := remainder
|
||||
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) {
|
||||
//mapping := remainder
|
||||
//var remainder = mapping
|
||||
//var err error
|
||||
if remainder == nil || len(remainder) < 0 {
|
||||
if remainder == nil || len(remainder) < 1 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "data shorter than expected",
|
||||
@@ -59,31 +70,21 @@ func ReadMappingValues(remainder []byte) (values *MappingValues, remainder_bytes
|
||||
return
|
||||
}
|
||||
map_values := make(MappingValues, 0)
|
||||
if len(remainder) < 1 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "data shorter than expected",
|
||||
}).Error("mapping contained no data")
|
||||
errs = []error{errors.New("mapping contained no data")}
|
||||
return
|
||||
}
|
||||
l := Integer(remainder[:2])
|
||||
length := l.Int()
|
||||
// - 2 bytes for map length bits
|
||||
mapping_len := len(mapping) - 2
|
||||
if mapping_len > length {
|
||||
int_map_length := map_length.Int()
|
||||
mapping_len := len(remainder)
|
||||
if mapping_len > int_map_length {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"mapping_bytes_length": mapping_len,
|
||||
"mapping_length_field": length,
|
||||
"mapping_length_field": int_map_length,
|
||||
"reason": "data longer than expected",
|
||||
}).Warn("mapping format warning")
|
||||
errs = append(errs, errors.New("warning parsing mapping: data exists beyond length of mapping"))
|
||||
} else if length > mapping_len {
|
||||
} else if int_map_length > mapping_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"mapping_bytes_length": mapping_len,
|
||||
"mapping_length_field": length,
|
||||
"mapping_length_field": int_map_length,
|
||||
"reason": "data shorter than expected",
|
||||
}).Warn("mapping format warning")
|
||||
errs = append(errs, errors.New("warning parsing mapping: mapping length exceeds provided data"))
|
||||
@@ -91,7 +92,7 @@ func ReadMappingValues(remainder []byte) (values *MappingValues, remainder_bytes
|
||||
|
||||
encounteredKeysMap := map[string]bool{}
|
||||
// pop off length bytes before parsing kv pairs
|
||||
remainder = remainder[2:]
|
||||
//remainder = remainder[2:]
|
||||
|
||||
for {
|
||||
// Read a key, breaking on fatal errors
|
||||
@@ -111,16 +112,16 @@ func ReadMappingValues(remainder []byte) (values *MappingValues, remainder_bytes
|
||||
break
|
||||
}
|
||||
|
||||
str, more, err := ReadI2PString(remainder)
|
||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||
remainder = more
|
||||
key_str := str
|
||||
key_str, more, err := ReadI2PString(remainder)
|
||||
if err != nil {
|
||||
if stopValueRead(err) {
|
||||
errs = append(errs, err)
|
||||
//return
|
||||
}
|
||||
}
|
||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||
remainder = more
|
||||
//log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
||||
|
||||
// Check if key has already been encountered in this mapping
|
||||
keyBytes, _ := key_str.Data()
|
||||
@@ -130,7 +131,9 @@ func ReadMappingValues(remainder []byte) (values *MappingValues, remainder_bytes
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "duplicate key in mapping",
|
||||
"key": string(key_str),
|
||||
}).Error("mapping format violation")
|
||||
log.Printf("DUPE: %s", key_str)
|
||||
errs = append(errs, errors.New("mapping format violation, duplicate key in mapping"))
|
||||
// Based on other implementations this does not seem to happen often?
|
||||
// Java throws an exception in this case, the base object is a Hashmap so the value is overwritten and an exception is thrown.
|
||||
@@ -142,33 +145,39 @@ func ReadMappingValues(remainder []byte) (values *MappingValues, remainder_bytes
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "expected =",
|
||||
"value:": string(remainder),
|
||||
}).Warn("mapping format violation")
|
||||
errs = append(errs, errors.New("mapping format violation, expected ="))
|
||||
log.Printf("ERRVAL: %s", remainder)
|
||||
break
|
||||
} else {
|
||||
remainder = remainder[1:]
|
||||
}
|
||||
remainder = remainder[1:]
|
||||
|
||||
// Read a value, breaking on fatal errors
|
||||
// and appending warnings
|
||||
str, more, err = ReadI2PString(remainder)
|
||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||
remainder = more
|
||||
val_str := str
|
||||
val_str, more, err := ReadI2PString(remainder)
|
||||
if err != nil {
|
||||
if stopValueRead(err) {
|
||||
errs = append(errs, err)
|
||||
//return
|
||||
}
|
||||
}
|
||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||
remainder = more
|
||||
//log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
||||
//log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str)
|
||||
if !beginsWith(remainder, 0x3b) {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "expected ;",
|
||||
"value:": string(remainder),
|
||||
}).Warn("mapping format violation")
|
||||
errs = append(errs, errors.New("mapping format violation, expected ;"))
|
||||
break
|
||||
} else {
|
||||
remainder = remainder[1:]
|
||||
}
|
||||
remainder = remainder[1:]
|
||||
|
||||
// Append the key-value pair and break if there is no more data to read
|
||||
map_values = append(map_values, [2]I2PString{key_str, val_str})
|
||||
|
@@ -38,28 +38,17 @@ func (str I2PString) Length() (length int, err error) {
|
||||
err = errors.New("error parsing string: zero length")
|
||||
return
|
||||
}
|
||||
l := Integer([]byte{byte(str[0])})
|
||||
l, _, _ := NewInteger(str, 1)
|
||||
length = l.Int()
|
||||
inferred_len := length + 1
|
||||
str_len := len(str)
|
||||
if inferred_len > str_len {
|
||||
str_len := len(str) - 1
|
||||
if length != str_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(I2PString) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"expected_bytes_length": inferred_len,
|
||||
"reason": "data shorter than specified",
|
||||
}).Warn("string format warning")
|
||||
"at": "(I2PString) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"reason": "data less than specified by length",
|
||||
}).Error("string format warning")
|
||||
err = errors.New("string parsing warning: string data is shorter than specified by length")
|
||||
} else if str_len > inferred_len {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(I2PString) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"expected_bytes_length": inferred_len,
|
||||
"reason": "data longer than specified",
|
||||
}).Warn("string format warning")
|
||||
err = errors.New("string parsing warning: string contains data beyond length")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -76,11 +65,14 @@ func (str I2PString) Data() (data string, err error) {
|
||||
data = string(str[1:])
|
||||
return
|
||||
case "string parsing warning: string contains data beyond length":
|
||||
data = string(str[1 : length+1])
|
||||
data = string(str[1:])
|
||||
return
|
||||
}
|
||||
}
|
||||
data = string(str[1:])
|
||||
if length == 0 {
|
||||
return
|
||||
}
|
||||
data = string(str[1 : length+1])
|
||||
return
|
||||
}
|
||||
|
||||
@@ -113,13 +105,14 @@ func ToI2PString(data string) (str I2PString, err error) {
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error) {
|
||||
str = I2PString(data)
|
||||
length, err := I2PString(data).Length()
|
||||
if err != nil && err.Error() == "string parsing warning: string contains data beyond length" {
|
||||
str = I2PString(data[:length+1])
|
||||
remainder = data[length+1:]
|
||||
err = nil
|
||||
length, _, err := NewInteger(data, 1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
data_len := length.Int()
|
||||
str = data[:data_len+1]
|
||||
remainder = data[data_len+1:]
|
||||
_, err = str.Length()
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@ package exportable
|
||||
import common "github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
keys_and_cert, _, _ := common.ReadKeysAndCert(data)
|
||||
keys_and_cert, _, _ := common.NewKeysAndCert(data)
|
||||
keys_and_cert.Certificate()
|
||||
keys_and_cert.PublicKey()
|
||||
keys_and_cert.SigningPublicKey()
|
||||
|
@@ -52,6 +52,10 @@ const (
|
||||
// Key Certificate Public Key Types
|
||||
const (
|
||||
KEYCERT_CRYPTO_ELG = iota
|
||||
KEYCERT_CRYPTO_P256
|
||||
KEYCERT_CRYPTO_P384
|
||||
KEYCERT_CRYPTO_P521
|
||||
KEYCERT_CRYPTO_X25519
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -73,7 +77,11 @@ const (
|
||||
|
||||
// PublicKey sizes for Public Key Types
|
||||
const (
|
||||
KEYCERT_CRYPTO_ELG_SIZE = 256
|
||||
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
|
||||
)
|
||||
|
||||
// Sizes of structures in KeyCertificates
|
||||
@@ -82,7 +90,7 @@ const (
|
||||
KEYCERT_SPK_SIZE = 128
|
||||
)
|
||||
|
||||
//type KeyCertificate []byte
|
||||
// type KeyCertificate []byte
|
||||
type KeyCertificate struct {
|
||||
*Certificate
|
||||
spkType Integer
|
||||
@@ -112,7 +120,7 @@ func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_ke
|
||||
return
|
||||
}
|
||||
data_len := len(data)
|
||||
if data_len < KEYCERT_PUBKEY_SIZE {
|
||||
if data_len < key_certificate.CryptoSize() {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(KeyCertificate) ConstructPublicKey",
|
||||
"data_len": data_len,
|
||||
@@ -127,6 +135,10 @@ func (key_certificate KeyCertificate) ConstructPublicKey(data []byte) (public_ke
|
||||
var elg_key crypto.ElgPublicKey
|
||||
copy(elg_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
||||
public_key = elg_key
|
||||
case KEYCERT_CRYPTO_X25519:
|
||||
var ed25519_key crypto.Ed25519PublicKey
|
||||
copy(ed25519_key[:], data[KEYCERT_PUBKEY_SIZE-KEYCERT_CRYPTO_ELG_SIZE:KEYCERT_PUBKEY_SIZE])
|
||||
public_key = ed25519_key
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -139,7 +151,7 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
|
||||
return
|
||||
}
|
||||
data_len := len(data)
|
||||
if data_len < KEYCERT_SPK_SIZE {
|
||||
if data_len < key_certificate.SignatureSize() {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(KeyCertificate) ConstructSigningPublicKey",
|
||||
"data_len": data_len,
|
||||
@@ -185,60 +197,51 @@ func (key_certificate KeyCertificate) ConstructSigningPublicKey(data []byte) (si
|
||||
// SignatureSize return the size of a Signature corresponding to the Key Certificate's SigningPublicKey type.
|
||||
func (key_certificate KeyCertificate) SignatureSize() (size int) {
|
||||
sizes := map[int]int{
|
||||
KEYCERT_SIGN_DSA_SHA1: 40,
|
||||
KEYCERT_SIGN_P256: 64,
|
||||
KEYCERT_SIGN_P384: 96,
|
||||
KEYCERT_SIGN_P521: 132,
|
||||
KEYCERT_SIGN_RSA2048: 256,
|
||||
KEYCERT_SIGN_RSA3072: 384,
|
||||
KEYCERT_SIGN_RSA4096: 512,
|
||||
KEYCERT_SIGN_ED25519: 64,
|
||||
KEYCERT_SIGN_ED25519PH: 64,
|
||||
KEYCERT_SIGN_DSA_SHA1: KEYCERT_SIGN_DSA_SHA1_SIZE,
|
||||
KEYCERT_SIGN_P256: KEYCERT_SIGN_P256_SIZE,
|
||||
KEYCERT_SIGN_P384: KEYCERT_SIGN_P384_SIZE,
|
||||
KEYCERT_SIGN_P521: KEYCERT_SIGN_P521_SIZE,
|
||||
KEYCERT_SIGN_RSA2048: KEYCERT_SIGN_RSA2048_SIZE,
|
||||
KEYCERT_SIGN_RSA3072: KEYCERT_SIGN_RSA3072_SIZE,
|
||||
KEYCERT_SIGN_RSA4096: KEYCERT_SIGN_RSA4096_SIZE,
|
||||
KEYCERT_SIGN_ED25519: KEYCERT_SIGN_ED25519_SIZE,
|
||||
KEYCERT_SIGN_ED25519PH: KEYCERT_SIGN_ED25519PH_SIZE,
|
||||
}
|
||||
key_type := key_certificate.SigningPublicKeyType()
|
||||
return sizes[int(key_type)]
|
||||
}
|
||||
|
||||
// CryptoSize return the size of a Public Key corresponding to the Key Certificate's PublicKey type.
|
||||
func (key_certificate KeyCertificate) CryptoSize() (size int) {
|
||||
sizes := map[int]int{
|
||||
KEYCERT_CRYPTO_ELG: KEYCERT_CRYPTO_ELG_SIZE,
|
||||
KEYCERT_CRYPTO_P256: KEYCERT_CRYPTO_P256_SIZE,
|
||||
KEYCERT_CRYPTO_P384: KEYCERT_CRYPTO_P384_SIZE,
|
||||
KEYCERT_CRYPTO_P521: KEYCERT_CRYPTO_P521_SIZE,
|
||||
KEYCERT_CRYPTO_X25519: KEYCERT_CRYPTO_X25519_SIZE,
|
||||
}
|
||||
key_type := key_certificate.PublicKeyType()
|
||||
return sizes[int(key_type)]
|
||||
}
|
||||
|
||||
// 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 NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder []byte, err error) {
|
||||
var certificate *Certificate
|
||||
certificate, remainder, err = ReadCertificate(bytes)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(bytes) < KEYCERT_MIN_SIZE {
|
||||
err = errors.New("error parsing key certificate: not enough data")
|
||||
}
|
||||
switch len(bytes) {
|
||||
case 4:
|
||||
key_certificate = &KeyCertificate{
|
||||
Certificate: certificate,
|
||||
spkType: Integer(bytes[4:]),
|
||||
cpkType: Integer([]byte{0}),
|
||||
}
|
||||
case 5:
|
||||
key_certificate = &KeyCertificate{
|
||||
Certificate: certificate,
|
||||
spkType: Integer(bytes[4:5]),
|
||||
cpkType: Integer([]byte{0}),
|
||||
}
|
||||
case 6:
|
||||
key_certificate = &KeyCertificate{
|
||||
Certificate: certificate,
|
||||
spkType: Integer(bytes[4:5]),
|
||||
cpkType: Integer(bytes[6:]),
|
||||
}
|
||||
default:
|
||||
key_certificate = &KeyCertificate{
|
||||
Certificate: certificate,
|
||||
spkType: Integer(bytes[4:5]),
|
||||
cpkType: Integer(bytes[6:7]),
|
||||
}
|
||||
key_certificate = &KeyCertificate{
|
||||
Certificate: certificate,
|
||||
spkType: Integer(bytes[4:5]),
|
||||
cpkType: Integer(bytes[6:7]),
|
||||
}
|
||||
remainder = bytes[7:]
|
||||
//key_certificate.PublicKey = NewPublicKey(bytes)
|
||||
remainder = bytes[KEYCERT_MIN_SIZE:]
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -165,51 +165,22 @@ func (keys_and_cert *KeysAndCert) Certificate() (cert *Certificate) {
|
||||
return keys_and_cert.KeyCertificate.Certificate
|
||||
}
|
||||
|
||||
//
|
||||
// Read a KeysAndCert from a slice of bytes, retuning it and the remaining data as well as any errors
|
||||
// encoutered parsing the KeysAndCert.
|
||||
//
|
||||
|
||||
// ReadKeysAndCert returns KeysAndCert from a []byte.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, err error) {
|
||||
/*data_len := len(data)
|
||||
if data_len < KEYS_AND_CERT_MIN_SIZE {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "ReadKeysAndCert",
|
||||
"data_len": data_len,
|
||||
"required_len": KEYS_AND_CERT_MIN_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error parsing keys and cert")
|
||||
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
|
||||
return
|
||||
}
|
||||
keys_and_cert = KeysAndCert(data[:KEYS_AND_CERT_MIN_SIZE])
|
||||
cert, _ := keys_and_cert.Certificate()
|
||||
cert_len := cert.Length()
|
||||
if cert_len == 0 {
|
||||
remainder = data[KEYS_AND_CERT_MIN_SIZE:]
|
||||
return
|
||||
}
|
||||
if data_len < KEYS_AND_CERT_MIN_SIZE+cert_len {
|
||||
keys_and_cert = append(keys_and_cert, data[KEYS_AND_CERT_MIN_SIZE:]...)
|
||||
//err = cert_len_err
|
||||
} else {
|
||||
keys_and_cert = append(keys_and_cert, data[KEYS_AND_CERT_MIN_SIZE:KEYS_AND_CERT_MIN_SIZE+cert_len]...)
|
||||
remainder = data[KEYS_AND_CERT_MIN_SIZE+cert_len:]
|
||||
}*/
|
||||
keys_and_cert_pointer, remainder, err := NewKeysAndCert(data)
|
||||
keys_and_cert = *keys_and_cert_pointer
|
||||
return
|
||||
}
|
||||
|
||||
// NewKeysAndCert creates a new *KeysAndCert from []byte using ReadKeysAndCert.
|
||||
// Returns a pointer to KeysAndCert unlike ReadKeysAndCert.
|
||||
func NewKeysAndCert(data []byte) (keys_and_cert *KeysAndCert, remainder []byte, err error) {
|
||||
data_len := len(data)
|
||||
keys_and_cert = &KeysAndCert{}
|
||||
if data_len < KEYS_AND_CERT_MIN_SIZE {
|
||||
if data_len < KEYS_AND_CERT_MIN_SIZE && data_len > KEYS_AND_CERT_DATA_SIZE {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "ReadKeysAndCert",
|
||||
"data_len": data_len,
|
||||
"required_len": KEYS_AND_CERT_MIN_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error parsing keys and cert")
|
||||
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
|
||||
keys_and_cert.KeyCertificate, remainder, _ = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
|
||||
return
|
||||
} else if data_len < KEYS_AND_CERT_DATA_SIZE {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "ReadKeysAndCert",
|
||||
"data_len": data_len,
|
||||
@@ -219,22 +190,22 @@ func NewKeysAndCert(data []byte) (keys_and_cert *KeysAndCert, remainder []byte,
|
||||
err = errors.New("error parsing KeysAndCert: data is smaller than minimum valid size")
|
||||
return
|
||||
}
|
||||
cert, remainder, err := NewKeyCertificate(data)
|
||||
keys_and_cert.KeyCertificate = cert
|
||||
keys_and_cert.KeyCertificate, remainder, err = NewKeyCertificate(data[KEYS_AND_CERT_DATA_SIZE:])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
padding := data[KEYS_AND_CERT_MIN_SIZE+cert.Length():]
|
||||
// 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
|
||||
// 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()])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
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 {
|
||||
return nil, nil, err
|
||||
}
|
||||
padding := data[KEYS_AND_CERT_PUBKEY_SIZE : KEYS_AND_CERT_DATA_SIZE-KEYS_AND_CERT_SPK_SIZE]
|
||||
keys_and_cert.padding = padding
|
||||
publicKey, err := cert.ConstructPublicKey(padding)
|
||||
keys_and_cert.publicKey = publicKey
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
signingPublicKey, err := cert.ConstructSigningPublicKey(padding)
|
||||
keys_and_cert.signingPublicKey = signingPublicKey
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return keys_and_cert, remainder, err
|
||||
}
|
||||
|
@@ -6,23 +6,17 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCertificateWithMissingData(t *testing.T) {
|
||||
/*func TestCertificateWithMissingData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := []byte{0x05, 0x00, 0x04, 0x00, 0x01}
|
||||
data := make([]byte, 128+256)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
|
||||
cert := keys_and_cert.Certificate()
|
||||
_, _, err := NewKeysAndCert(data)
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error())
|
||||
}
|
||||
cert_bytes := cert.Bytes()
|
||||
if assert.Equal(len(cert_data), len(cert_bytes)) {
|
||||
assert.Equal(cert_bytes, cert_data, "keys_and_cert.Certificate() did not return available data when cert was missing some data")
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
func TestCertificateWithValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
@@ -30,10 +24,11 @@ func TestCertificateWithValidData(t *testing.T) {
|
||||
cert_data := []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}
|
||||
data := make([]byte, 128+256)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
assert.Nil(err)
|
||||
|
||||
cert := keys_and_cert.Certificate()
|
||||
assert.Nil(err)
|
||||
|
||||
cert_bytes := cert.Bytes()
|
||||
if assert.Equal(len(cert_data), len(cert_bytes)) {
|
||||
assert.Equal(cert_bytes, cert_data, "keys_and_cert.Certificate() did not return correct data with valid cert")
|
||||
@@ -48,7 +43,7 @@ func TestPublicKeyWithBadData(t *testing.T) {
|
||||
data := make([]byte, 128)
|
||||
data = append(data, pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
pub_key := keys_and_cert.PublicKey()
|
||||
if assert.NotNil(err) {
|
||||
@@ -65,7 +60,7 @@ func TestPublicKeyWithBadCertificate(t *testing.T) {
|
||||
data := make([]byte, 128)
|
||||
data = append(data, pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
pub_key := keys_and_cert.PublicKey()
|
||||
if assert.NotNil(err) {
|
||||
@@ -82,7 +77,7 @@ func TestPublicKeyWithNullCertificate(t *testing.T) {
|
||||
data := make([]byte, 128)
|
||||
data = append(data, pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
pub_key := keys_and_cert.PublicKey()
|
||||
assert.Nil(err)
|
||||
@@ -97,7 +92,7 @@ func TestPublicKeyWithKeyCertificate(t *testing.T) {
|
||||
data := make([]byte, 128)
|
||||
data = append(data, pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
pub_key := keys_and_cert.PublicKey()
|
||||
assert.Nil(err)
|
||||
@@ -112,7 +107,7 @@ func TestSigningPublicKeyWithBadData(t *testing.T) {
|
||||
data := make([]byte, 93)
|
||||
data = append(data, pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||
if assert.NotNil(err) {
|
||||
@@ -129,7 +124,7 @@ func TestSigningPublicKeyWithBadCertificate(t *testing.T) {
|
||||
data := make([]byte, 128)
|
||||
data = append(data, pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||
if assert.NotNil(err) {
|
||||
@@ -146,7 +141,7 @@ func TestSigningPublicKeyWithNullCertificate(t *testing.T) {
|
||||
signing_pub_key_data := make([]byte, 128)
|
||||
data := append(pub_key_data, signing_pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||
assert.Nil(err)
|
||||
@@ -161,18 +156,18 @@ func TestSigningPublicKeyWithKeyCertificate(t *testing.T) {
|
||||
signing_pub_key_data := make([]byte, 128)
|
||||
data := append(pub_key_data, signing_pub_key_data...)
|
||||
data = append(data, cert_data...)
|
||||
keys_and_cert, _, err := ReadKeysAndCert(data)
|
||||
keys_and_cert, _, err := NewKeysAndCert(data)
|
||||
|
||||
signing_pub_key := keys_and_cert.SigningPublicKey()
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(signing_pub_key_data), signing_pub_key.Len())
|
||||
}
|
||||
|
||||
func TestReadKeysAndCertWithMissingData(t *testing.T) {
|
||||
func TestNewKeysAndCertWithMissingData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := make([]byte, 128)
|
||||
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||
_, remainder, err := NewKeysAndCert(cert_data)
|
||||
assert.Equal(0, len(remainder))
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error parsing KeysAndCert: data is smaller than minimum valid size", err.Error())
|
||||
@@ -180,56 +175,56 @@ func TestReadKeysAndCertWithMissingData(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestReadKeysAndCertWithMissingCertData(t *testing.T) {
|
||||
func TestNewKeysAndCertWithMissingCertData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := make([]byte, 128+256)
|
||||
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01}...)
|
||||
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||
_, remainder, err := NewKeysAndCert(cert_data)
|
||||
assert.Equal(0, len(remainder))
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadKeysAndCertWithValidDataWithCertificate(t *testing.T) {
|
||||
func TestNewKeysAndCertWithValidDataWithCertificate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := make([]byte, 128+256)
|
||||
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00}...)
|
||||
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||
_, remainder, err := NewKeysAndCert(cert_data)
|
||||
assert.Equal(0, len(remainder))
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
func TestReadKeysAndCertWithValidDataWithoutCertificate(t *testing.T) {
|
||||
func TestNewKeysAndCertWithValidDataWithoutCertificate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := make([]byte, 128+256)
|
||||
cert_data = append(cert_data, []byte{0x00, 0x00, 0x00}...)
|
||||
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||
_, remainder, err := NewKeysAndCert(cert_data)
|
||||
assert.Equal(0, len(remainder))
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
func TestReadKeysAndCertWithValidDataWithCertificateAndRemainder(t *testing.T) {
|
||||
func TestNewKeysAndCertWithValidDataWithCertificateAndRemainder(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := make([]byte, 128+256)
|
||||
cert_data = append(cert_data, []byte{0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x41}...)
|
||||
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||
_, remainder, err := NewKeysAndCert(cert_data)
|
||||
if assert.Equal(1, len(remainder)) {
|
||||
assert.Equal("A", string(remainder[0]))
|
||||
}
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
func TestReadKeysAndCertWithValidDataWithoutCertificateAndRemainder(t *testing.T) {
|
||||
func TestNewKeysAndCertWithValidDataWithoutCertificateAndRemainder(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cert_data := make([]byte, 128+256)
|
||||
cert_data = append(cert_data, []byte{0x00, 0x00, 0x00, 0x41}...)
|
||||
_, remainder, err := ReadKeysAndCert(cert_data)
|
||||
_, remainder, err := NewKeysAndCert(cert_data)
|
||||
if assert.Equal(1, len(remainder)) {
|
||||
assert.Equal("A", string(remainder[0]))
|
||||
}
|
||||
|
@@ -132,7 +132,10 @@ type LeaseSet struct {
|
||||
|
||||
// Destination returns the Destination as []byte.
|
||||
func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
||||
keys_and_cert, _, err := ReadKeysAndCert(lease_set)
|
||||
keys_and_cert, _, err := NewKeysAndCert(lease_set)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
destination, _, err = ReadDestination(keys_and_cert.Bytes())
|
||||
return
|
||||
}
|
||||
@@ -140,7 +143,7 @@ func (lease_set LeaseSet) Destination() (destination Destination, err error) {
|
||||
// PublicKey returns the public key as crypto.ElgPublicKey.
|
||||
// Returns errors encountered during parsing.
|
||||
func (lease_set LeaseSet) PublicKey() (public_key crypto.ElgPublicKey, err error) {
|
||||
_, remainder, err := ReadKeysAndCert(lease_set)
|
||||
_, remainder, err := NewKeysAndCert(lease_set)
|
||||
remainder_len := len(remainder)
|
||||
if remainder_len < LEASE_SET_PUBKEY_SIZE {
|
||||
log.WithFields(log.Fields{
|
||||
@@ -212,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.
|
||||
// returns errors encountered during parsing.
|
||||
func (lease_set LeaseSet) LeaseCount() (count int, err error) {
|
||||
_, remainder, err := ReadKeysAndCert(lease_set)
|
||||
_, remainder, err := NewKeysAndCert(lease_set)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@@ -67,7 +67,6 @@ type RouterAddress struct {
|
||||
expiration *Date
|
||||
transport_style *I2PString
|
||||
options *Mapping
|
||||
parserErr error
|
||||
}
|
||||
|
||||
// Bytes returns the router address as a []byte.
|
||||
@@ -83,7 +82,7 @@ func (router_address RouterAddress) Bytes() []byte {
|
||||
} else {
|
||||
bytes = append(bytes, strData...)
|
||||
}
|
||||
//bytes = append(bytes, router_address.options.Bytes()...)
|
||||
bytes = append(bytes, router_address.options.Data()...)
|
||||
return bytes
|
||||
}
|
||||
|
||||
@@ -107,29 +106,8 @@ func (router_address RouterAddress) Options() Mapping {
|
||||
return *router_address.options
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the RouterAddress is empty or if it is too small to contain valid data.
|
||||
//
|
||||
func (router_address RouterAddress) checkValid() (err error, exit bool) {
|
||||
/*addr_len := len(router_address)
|
||||
exit = false
|
||||
if addr_len == 0 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) checkValid",
|
||||
"reason": "no data",
|
||||
}).Error("invalid router address")
|
||||
err = errors.New("error parsing RouterAddress: no data")
|
||||
exit = true
|
||||
} else if addr_len < ROUTER_ADDRESS_MIN_SIZE {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) checkValid",
|
||||
"reason": "data too small (len < ROUTER_ADDRESS_MIN_SIZE)",
|
||||
}).Warn("router address format warning")
|
||||
err = errors.New("warning parsing RouterAddress: data too small")
|
||||
}*/
|
||||
if router_address.parserErr != nil {
|
||||
exit = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -137,54 +115,40 @@ func (router_address RouterAddress) checkValid() (err error, exit bool) {
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadRouterAddress(data []byte) (router_address RouterAddress, remainder []byte, err error) {
|
||||
if data == nil || len(data) == 0 {
|
||||
log.WithField("at", "(RouterAddress) ReadRouterAddress").Error("no data")
|
||||
if len(data) == 0 {
|
||||
log.WithField("at", "(RouterAddress) ReadRouterAddress").Error("error parsing RouterAddress: no data")
|
||||
err = errors.New("error parsing RouterAddress: no data")
|
||||
router_address.parserErr = err
|
||||
return
|
||||
}
|
||||
cost, remainder, err := NewInteger([]byte{data[0]}, 1)
|
||||
router_address.cost = cost
|
||||
router_address.cost, remainder, err = NewInteger(data, 1)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||
"reason": "error parsing cost",
|
||||
}).Warn("error parsing RouterAddress")
|
||||
router_address.parserErr = err
|
||||
}
|
||||
expiration, remainder, err := NewDate(remainder)
|
||||
router_address.expiration = expiration
|
||||
router_address.expiration, remainder, err = NewDate(remainder)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||
"reason": "error parsing expiration",
|
||||
}).Error("error parsing RouterAddress")
|
||||
router_address.parserErr = err
|
||||
}
|
||||
transport_style, remainder, err := NewI2PString(remainder)
|
||||
router_address.transport_style = transport_style
|
||||
router_address.transport_style, remainder, err = NewI2PString(remainder)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||
"reason": "error parsing transport_style",
|
||||
}).Error("error parsing RouterAddress")
|
||||
router_address.parserErr = err
|
||||
}
|
||||
options, remainder, errs := NewMapping(remainder)
|
||||
var errs []error
|
||||
router_address.options, remainder, errs = NewMapping(remainder)
|
||||
for _, err := range errs {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||
"reason": "error parsing options",
|
||||
"error": err,
|
||||
}).Error("error parsing RouterAddress")
|
||||
router_address.parserErr = err
|
||||
}
|
||||
router_address.options = options
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterAddress) ReadNewRouterAddress",
|
||||
"reason": "error parsing options",
|
||||
}).Error("error parsing RouterAddress")
|
||||
router_address.parserErr = err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@ package router_info
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
. "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
. "github.com/go-i2p/go-i2p/lib/common/router_address"
|
||||
@@ -13,6 +15,9 @@ import (
|
||||
|
||||
const ROUTER_INFO_MIN_SIZE = 439
|
||||
|
||||
var MIN_GOOD_VERSION = 59
|
||||
const MAX_GOOD_VERSION = 99
|
||||
|
||||
/*
|
||||
[RouterInfo]
|
||||
Accurate for version 0.9.49
|
||||
@@ -110,7 +115,6 @@ type RouterInfo struct {
|
||||
func (router_info RouterInfo) Bytes() ([]byte, error) {
|
||||
var err error
|
||||
var bytes []byte
|
||||
|
||||
bytes = append(bytes, router_info.router_identity.KeysAndCert.Bytes()...)
|
||||
bytes = append(bytes, router_info.published.Bytes()...)
|
||||
bytes = append(bytes, router_info.size.Bytes()...)
|
||||
@@ -118,8 +122,8 @@ func (router_info RouterInfo) Bytes() ([]byte, error) {
|
||||
bytes = append(bytes, router_address.Bytes()...)
|
||||
}
|
||||
bytes = append(bytes, router_info.peer_size.Bytes()...)
|
||||
//bytes = append(bytes, router_info.options.Bytes()...)
|
||||
bytes = append(bytes, []byte(*router_info.signature)...)
|
||||
bytes = append(bytes, router_info.options.Data()...)
|
||||
//bytes = append(bytes, []byte(*router_info.signature)...)
|
||||
|
||||
return bytes, err
|
||||
}
|
||||
@@ -251,6 +255,14 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
err = errors.New("error parsing router info: not enough data")
|
||||
}
|
||||
size, remainder, err := NewInteger(remainder, 1)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterInfo) ReadRouterInfo",
|
||||
"data_len": len(remainder),
|
||||
"required_len": size.Int(),
|
||||
"reason": "read error",
|
||||
}).Error("error parsing router info size")
|
||||
}
|
||||
info.size = size
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
@@ -261,25 +273,23 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
}).Error("error parsing router info")
|
||||
err = errors.New("error parsing router info: not enough data")
|
||||
}
|
||||
addresses := make([]*RouterAddress, size.Int())
|
||||
for i := 0; i < size.Int(); i++ {
|
||||
address, remainder, err := NewRouterAddress(remainder)
|
||||
address, more, err := NewRouterAddress(remainder)
|
||||
remainder = more
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterInfo) ReadRouterInfo",
|
||||
"data_len": len(remainder),
|
||||
//"required_len": ROUTER_ADDRESS_SIZE,
|
||||
"reason": "not enough data",
|
||||
}).Error("error parsing router info")
|
||||
}).Error("error parsing router address")
|
||||
err = errors.New("error parsing router info: not enough data")
|
||||
}
|
||||
addresses = append(addresses, address)
|
||||
info.addresses = append(info.addresses, address)
|
||||
}
|
||||
info.addresses = addresses
|
||||
peer_size := Integer(remainder[:1])
|
||||
info.peer_size = &peer_size
|
||||
remainder = remainder[1:]
|
||||
options, remainder, errs := NewMapping(remainder)
|
||||
info.peer_size, remainder, err = NewInteger(remainder, 1)
|
||||
var errs []error
|
||||
info.options, remainder, errs = NewMapping(remainder)
|
||||
if len(errs) != 0 {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterInfo) ReadRouterInfo",
|
||||
@@ -293,7 +303,6 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
}
|
||||
err = errors.New("error parsing router info: " + estring)
|
||||
}
|
||||
info.options = options
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(RouterInfo) ReadRouterInfo",
|
||||
@@ -306,6 +315,61 @@ func ReadRouterInfo(bytes []byte) (info RouterInfo, remainder []byte, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func (router_info *RouterInfo) RouterCapabilities() string {
|
||||
str, err := ToI2PString("caps")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(router_info.options.Values().Get(str))
|
||||
}
|
||||
|
||||
func (router_info *RouterInfo) RouterVersion() string {
|
||||
str, err := ToI2PString("router.version")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(router_info.options.Values().Get(str))
|
||||
}
|
||||
|
||||
func (router_info *RouterInfo) GoodVersion() bool {
|
||||
version := router_info.RouterVersion()
|
||||
v := strings.Split(version, ".")
|
||||
if len(v) != 3 {
|
||||
return false
|
||||
}
|
||||
if v[0] == "0" {
|
||||
if v[1] == "9" {
|
||||
val, _ := strconv.Atoi(v[2])
|
||||
if val >= MIN_GOOD_VERSION && val <= MAX_GOOD_VERSION {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (router_info *RouterInfo) UnCongested() bool {
|
||||
caps := router_info.RouterCapabilities()
|
||||
if strings.Contains(caps, "K") {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(caps, "G") {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(caps, "E") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (router_info *RouterInfo) Reachable() bool {
|
||||
caps := router_info.RouterCapabilities()
|
||||
if strings.Contains(caps, "U") {
|
||||
return false
|
||||
}
|
||||
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) {
|
||||
|
@@ -1,4 +1,2 @@
|
||||
//
|
||||
// package for i2p specific crpytography
|
||||
//
|
||||
package crypto
|
||||
|
@@ -2,10 +2,16 @@ package crypto
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var Ed25519EncryptTooBig = errors.New("failed to encrypt data, too big for Ed25519")
|
||||
|
||||
type Ed25519PublicKey []byte
|
||||
|
||||
type Ed25519Verifier struct {
|
||||
@@ -19,6 +25,77 @@ func (k Ed25519PublicKey) NewVerifier() (v Verifier, err error) {
|
||||
return temp, nil
|
||||
}
|
||||
|
||||
func (k Ed25519PublicKey) Len() int {
|
||||
return len(k)
|
||||
}
|
||||
|
||||
func createEd25519PublicKey(data []byte) (k *ed25519.PublicKey) {
|
||||
if len(data) == 256 {
|
||||
k2 := ed25519.PublicKey{}
|
||||
copy(k2[:], data)
|
||||
k = &k2
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createEd25519Encryption(pub *ed25519.PublicKey, rand io.Reader) (enc *Ed25519Encryption, 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 = &Ed25519Encryption{}
|
||||
}*/
|
||||
return
|
||||
}
|
||||
|
||||
type Ed25519Encryption struct {
|
||||
p, a, b1 *big.Int
|
||||
}
|
||||
|
||||
func (ed25519 *Ed25519Encryption) Encrypt(data []byte) (enc []byte, err error) {
|
||||
return ed25519.EncryptPadding(data, true)
|
||||
}
|
||||
|
||||
func (ed25519 *Ed25519Encryption) EncryptPadding(data []byte, zeroPadding bool) (encrypted []byte, err error) {
|
||||
if len(data) > 222 {
|
||||
err = Ed25519EncryptTooBig
|
||||
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(ed25519.b1, m), ed25519.p).Bytes()
|
||||
|
||||
if zeroPadding {
|
||||
encrypted = make([]byte, 514)
|
||||
copy(encrypted[1:], ed25519.a.Bytes())
|
||||
copy(encrypted[258:], b)
|
||||
} else {
|
||||
encrypted = make([]byte, 512)
|
||||
copy(encrypted, ed25519.a.Bytes())
|
||||
copy(encrypted[256:], b)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (elg Ed25519PublicKey) NewEncrypter() (enc Encrypter, err error) {
|
||||
k := createEd25519PublicKey(elg[:])
|
||||
enc, err = createEd25519Encryption(k, rand.Reader)
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Ed25519Verifier) VerifyHash(h, sig []byte) (err error) {
|
||||
if len(sig) != ed25519.SignatureSize {
|
||||
err = ErrBadSignatureSize
|
||||
|
@@ -5,9 +5,10 @@ import (
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"golang.org/x/crypto/openpgp/elgamal"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"golang.org/x/crypto/openpgp/elgamal"
|
||||
)
|
||||
|
||||
var elgp = new(big.Int).SetBytes([]byte{
|
||||
|
@@ -23,9 +23,7 @@ func (hk HMACKey) xor(p byte) (i []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// do i2p hmac
|
||||
//
|
||||
func I2PHMAC(data []byte, k HMACKey) (d HMACDigest) {
|
||||
|
||||
buff := make([]byte, 64+len(data))
|
||||
|
@@ -1,5 +1 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
package netdb
|
||||
|
@@ -50,9 +50,7 @@ func (db StdNetDB) Path() string {
|
||||
return string(db)
|
||||
}
|
||||
|
||||
//
|
||||
// return how many routers we know about in our network database
|
||||
//
|
||||
func (db StdNetDB) Size() (routers int) {
|
||||
// TODO: implement this
|
||||
var err error
|
||||
|
@@ -14,47 +14,50 @@
|
||||
// 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.
|
||||
// }
|
||||
//
|
||||
// // 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))
|
||||
//
|
||||
// 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.
|
||||
// }
|
||||
//
|
||||
// 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
|
||||
|
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
i2np messages transports
|
||||
/*
|
||||
*
|
||||
|
||||
i2np messages transports
|
||||
*/
|
||||
package transport
|
||||
|
@@ -1,123 +1,15 @@
|
||||
package noise
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/flynn/noise"
|
||||
)
|
||||
|
||||
func ComposeInitiatorHandshakeMessage(s noise.DHKey, rs []byte, payload []byte, ePrivate []byte) (negData, msg []byte, state *noise.HandshakeState, err error) {
|
||||
if len(rs) != 0 && len(rs) != noise.DH25519.DHLen() {
|
||||
|
||||
return nil, nil, nil, errors.New("only 32 byte curve25519 public keys are supported")
|
||||
|
||||
}
|
||||
var pattern noise.HandshakePattern
|
||||
negData = make([]byte, 6)
|
||||
copy(negData, negotiationData)
|
||||
pattern = noise.HandshakeIK
|
||||
negData[5] = NOISE_PATTERN_IK
|
||||
var random io.Reader
|
||||
if len(ePrivate) == 0 {
|
||||
random = rand.Reader
|
||||
} else {
|
||||
random = bytes.NewBuffer(ePrivate)
|
||||
}
|
||||
prologue := make([]byte, 2, uint16Size+len(negData))
|
||||
binary.BigEndian.PutUint16(prologue, uint16(len(negData)))
|
||||
prologue = append(prologue, negData...)
|
||||
prologue = append(initString, prologue...)
|
||||
state, err = noise.NewHandshakeState(noise.Config{
|
||||
StaticKeypair: s,
|
||||
Initiator: true,
|
||||
Pattern: pattern,
|
||||
CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherAESGCM, noise.HashBLAKE2b),
|
||||
PeerStatic: rs,
|
||||
Prologue: prologue,
|
||||
Random: random,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
padBuf := make([]byte, 2+len(payload))
|
||||
copy(padBuf[2:], payload)
|
||||
msg, _, _, err = state.WriteMessage(msg, padBuf)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *NoiseSession) RunClientHandshake() error {
|
||||
var (
|
||||
negData, msg []byte
|
||||
state *noise.HandshakeState
|
||||
err error
|
||||
)
|
||||
if negData, msg, state, err = ComposeInitiatorHandshakeMessage(c.StaticKey, nil, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = c.Write(negData); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = c.Write(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
//read negotiation data
|
||||
/*if err := c.readPacket(); err != nil {
|
||||
return err
|
||||
}
|
||||
negotiationData := c.handshakeBuffer.Next(c.handshakeBuffer.Len())
|
||||
//read noise message
|
||||
if err := c.readPacket(); err != nil {
|
||||
return err
|
||||
}
|
||||
msg = c.handshakeBuffer.Next(c.handshakeBuffer.Len())
|
||||
if len(negotiationData) != 0 || len(msg) == 0 {
|
||||
return errors.New("Server returned error")
|
||||
}
|
||||
// cannot reuse msg for read, need another buf
|
||||
inBlock := c.NoiseTransport.newBlock()
|
||||
inBlock.reserve(len(msg))*/
|
||||
var payload int
|
||||
payload, c.CipherState, c.NoiseTransport.CipherState, err = state.ReadMessage(inBlock.data, msg)
|
||||
/*if err != nil {
|
||||
c.NoiseTransport.freeBlock(inBlock)
|
||||
return err
|
||||
}*/
|
||||
err = c.processCallback(state.PeerStatic(), payload)
|
||||
if err != nil {
|
||||
c.NoiseTransport.freeBlock(inBlock)
|
||||
return err
|
||||
}
|
||||
/*c.NoiseTransport.freeBlock(inBlock)
|
||||
if c.CipherState == nil && c.NoiseTransport.CipherState == nil {
|
||||
b := c.newBlock()
|
||||
if b.data, c.CipherState, c.NoiseTransport.CipherState, err = state.WriteMessage(b.data, pad(c.config.Payload)); err != nil {
|
||||
c.freeBlock(b)
|
||||
return err
|
||||
}
|
||||
if _, err = c.Write(nil); err != nil {
|
||||
c.freeBlock(b)
|
||||
return err
|
||||
}
|
||||
if _, err = c.Write(b.data); err != nil {
|
||||
c.freeBlock(b)
|
||||
return err
|
||||
}
|
||||
c.freeBlock(b)
|
||||
if c.CipherState == nil || c.NoiseTransport.CipherState == nil {
|
||||
log.WithFields(log.Fields{
|
||||
"at": "(NoiseSession) RunClientHandshake",
|
||||
"reason": "unsupported session",
|
||||
}).Error("unsupported session")
|
||||
return errors.New("unsupported session")
|
||||
}
|
||||
}
|
||||
*/
|
||||
//c.in.padding, c.out.padding = c.config.Padding, c.config.Padding
|
||||
//c.channelBinding = state.ChannelBinding()
|
||||
c.handshakeComplete = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
|
||||
i2p ssu transport implementation
|
||||
|
||||
*/
|
||||
package ssu
|
||||
|
@@ -380,8 +380,9 @@ func (delivery_instructions DeliveryInstructions) TunnelID() (tunnel_id uint32,
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// 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 (delivery_instructions DeliveryInstructions) Hash() (hash common.Hash, err error) {
|
||||
delivery_type, err := delivery_instructions.DeliveryType()
|
||||
if err != nil {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
i2p garlic tunnel implementation
|
||||
i2p garlic tunnel implementation
|
||||
*/
|
||||
package tunnel
|
||||
|
@@ -153,10 +153,8 @@ func (decrypted_tunnel_message DecryptedTunnelMessage) Checksum() crypto.TunnelI
|
||||
return decrypted_tunnel_message[4+16 : 4+4+16]
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the contents of a decrypted tunnel message that contain the data for the
|
||||
// DeliveryInstructions.
|
||||
//
|
||||
func (decrypted_tunnel_message DecryptedTunnelMessage) deliveryInstructionData() []byte {
|
||||
data_area := decrypted_tunnel_message[4+4+16:]
|
||||
for i := 0; i < len(data_area); i++ {
|
||||
@@ -167,11 +165,8 @@ func (decrypted_tunnel_message DecryptedTunnelMessage) deliveryInstructionData()
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
//
|
||||
// Returns a slice of DeliveryInstructionWithFragment structures, which all of the Delivery Instructions
|
||||
// in the tunnel message and their corresponding MessageFragment structures.
|
||||
//
|
||||
//
|
||||
func (decrypted_tunnel_message DecryptedTunnelMessage) DeliveryInstructionsWithFragments() []DeliveryInstructionsWithFragment {
|
||||
set := make([]DeliveryInstructionsWithFragment, 0)
|
||||
data := decrypted_tunnel_message.deliveryInstructionData()
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package signals
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package signals
|
||||
|
Reference in New Issue
Block a user