-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdestination.go
170 lines (160 loc) · 4.63 KB
/
destination.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package go_i2cp
import (
"errors"
"fmt"
"math/big"
"os"
"strings"
)
const tag = DESTINATION
const PUB_KEY_SIZE = 256
const DIGEST_SIZE = 40
const DEST_SIZE = 4096
type Destination struct {
cert *Certificate
sgk SignatureKeyPair
signPubKey *big.Int
pubKey [PUB_KEY_SIZE]byte
digest [DIGEST_SIZE]byte
b32 string
b64 string
}
func NewDestination() (dest *Destination, err error) {
dest = &Destination{}
nullCert := NewCertificate(CERTIFICATE_NULL)
dest.cert = &nullCert
dest.sgk, err = GetCryptoInstance().SignatureKeygen(DSA_SHA1)
dest.signPubKey = dest.sgk.pub.Y
dest.generateB32()
dest.generateB64()
return
}
func NewDestinationFromMessage(stream *Stream) (dest *Destination, err error) {
dest = &Destination{}
_, err = stream.Read(dest.pubKey[:])
if err != nil {
return
}
dest.signPubKey, err = GetCryptoInstance().PublicKeyFromStream(DSA_SHA1, stream)
if err != nil {
return
}
dest.sgk = SignatureKeyPair{}
dest.sgk.priv.Y = dest.signPubKey
dest.sgk.pub.Y = dest.signPubKey
var cert Certificate
cert, err = NewCertificateFromMessage(stream)
if err != nil {
return
}
dest.cert = &cert
dest.generateB32()
dest.generateB64()
return dest, err
}
func NewDestinationFromStream(stream *Stream) (dest *Destination, err error) {
var cert Certificate
var pubKeyLen uint16
dest = &Destination{}
cert, err = NewCertificateFromStream(stream)
dest.cert = &cert
dest.sgk, err = GetCryptoInstance().SignatureKeyPairFromStream(stream)
pubKeyLen, err = stream.ReadUint16()
if pubKeyLen != PUB_KEY_SIZE {
Fatal(tag, "Failed to load pub key len, %d != %d", pubKeyLen, PUB_KEY_SIZE)
}
_, err = stream.Read(dest.pubKey[:])
dest.generateB32()
dest.generateB64()
return
}
func NewDestinationFromBase64(base64 string) (dest *Destination, err error) {
/* Same as decode, except from a filesystem / URL friendly set of characters,
* replacing / with ~, and + with -
*/
// see https://javadoc.freenetproject.org/freenet/support/Base64.html
if len(base64) == 0 {
err = errors.New("empty string")
return
}
var replaced string
// Convert from freenet to standard
replaced = strings.Replace(base64, "~", "/", -1)
replaced = strings.Replace(replaced, "-", "+", -1)
stream := NewStream([]byte(replaced))
var decoded *Stream
decoded, err = GetCryptoInstance().DecodeStream(CODEC_BASE64, stream)
return NewDestinationFromMessage(decoded)
}
func NewDestinationFromFile(file *os.File) (*Destination, error) {
var stream Stream
stream.loadFile(file)
return NewDestinationFromStream(&stream)
}
func (dest *Destination) Copy() (newDest Destination) {
newDest.cert = dest.cert
newDest.signPubKey = dest.signPubKey
newDest.pubKey = dest.pubKey
newDest.sgk = dest.sgk
newDest.b32 = dest.b32
newDest.b64 = dest.b64
newDest.digest = dest.digest
return
}
func (dest *Destination) WriteToFile(filename string) (err error) {
stream := NewStream(make([]byte, 0, DEST_SIZE))
dest.WriteToStream(stream)
var file *os.File
file, err = os.Open(filename)
stream.WriteTo(file)
file.Close()
return
}
func (dest *Destination) WriteToMessage(stream *Stream) (err error) {
lena := len(dest.pubKey)
_ = lena
_, err = stream.Write(dest.pubKey[:])
_, err = stream.Write(dest.signPubKey.Bytes()) //GetCryptoInstance().WriteSignatureToStream(&dest.sgk, stream)
err = dest.cert.WriteToMessage(stream)
lenb := stream.Len()
_ = lenb
return
}
func (dest *Destination) WriteToStream(stream *Stream) (err error) {
err = dest.cert.WriteToStream(stream)
err = GetCryptoInstance().WriteSignatureToStream(&dest.sgk, stream)
err = stream.WriteUint16(PUB_KEY_SIZE)
_, err = stream.Write(dest.pubKey[:])
return
}
//Doesn't seem to be used anywhere??
func (dest *Destination) Verify() (verified bool, err error) {
stream := NewStream(make([]byte, 0, DEST_SIZE))
dest.WriteToMessage(stream)
stream.Write(dest.digest[:])
return GetCryptoInstance().VerifyStream(&dest.sgk, stream)
}
func (dest *Destination) generateB32() {
stream := NewStream(make([]byte, 0, DEST_SIZE))
dest.WriteToMessage(stream)
cpt := GetCryptoInstance()
hash := cpt.HashStream(HASH_SHA256, stream)
b32 := cpt.EncodeStream(CODEC_BASE32, hash)
length := b32.Len()
_ = length
dest.b32 = string(b32.Bytes())
dest.b32 += ".b32.i2p"
Debug(tag, "New destination %s", dest.b32)
}
func (dest *Destination) generateB64() {
stream := NewStream(make([]byte, 0, DEST_SIZE))
dest.WriteToMessage(stream)
cpt := GetCryptoInstance()
if stream.Len() > 0 {
fmt.Printf("Stream len %d \n", stream.Len())
}
b64B := cpt.EncodeStream(CODEC_BASE64, stream)
replaced := strings.Replace(string(b64B.Bytes()), "/", "~", -1)
replaced = strings.Replace(replaced, "/", "~", -1)
dest.b64 = replaced
}