/
info.go
118 lines (101 loc) · 2.42 KB
/
info.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
package raopd
import (
"bytes"
"crypto/rsa"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"net"
"os"
)
// Contains generic information relevant to all servers/clients
type info struct {
key *rsa.PrivateKey // Move all code related to this here...
}
var authlog = getLogger("raopd.auth", "RAOP Authentication Data")
func makeInfo(keyfilename string) (*info, error) {
i := &info{}
file, err := os.Open(keyfilename)
if err != nil {
return nil, err
}
i.key, err = getRSAPrivateKey(file)
return i, err
}
var ipv4prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
func isIPv4(ipaddr net.IP) bool {
for ii, cb := range ipv4prefix {
if ipaddr[ii] != cb {
return false
}
}
return true
}
func ipToBytes(ipaddr net.IP) []byte {
ipb := []byte(ipaddr)
if len(ipb) == 4 {
return ipb
}
if isIPv4(ipaddr) {
return ipaddr[12:16]
} else {
return ipaddr
}
}
func (i *info) decodeBase64(b64 string) ([]byte, error) {
authlog.Debug.Println("base64 string", b64)
enc := base64.RawStdEncoding
if b64[len(b64)-1] == '=' {
enc = base64.StdEncoding
}
return enc.DecodeString(b64)
}
func (i *info) rsaKeySign(b64digest string, ipaddr net.IP, hwaddr net.HardwareAddr) (string, error) {
buffer := bytes.NewBufferString("")
digest, err := i.decodeBase64(b64digest)
if err != nil {
return "", err
}
authlog.Debug.Println("digest", hex.Dump(digest))
buffer.Write(digest)
length := 0
ipb := ipToBytes(ipaddr)
authlog.Debug.Println("len(ipaddr)=", len(ipaddr))
if len(ipb) == 4 {
authlog.Debug.Println("ipaddr IPv4", hex.Dump(ipb))
length = 32
} else {
authlog.Debug.Println("ipaddr IPv6", hex.Dump(ipb))
length = 38
}
buffer.Write(ipb)
authlog.Debug.Println("hwaddr", hex.Dump(hwaddr))
buffer.Write(hwaddr)
buffer.Write([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
bb := buffer.Bytes()[0:length]
dst, err := rsa.SignPKCS1v15(nil, i.key, 0, bb)
if err != nil {
return "", err
}
sign := base64.RawStdEncoding.EncodeToString(dst)
return sign, nil
}
func (i *info) rsaKeyDecrypt(b64encrypted string) ([]byte, error) {
label := []byte{}
encrypted, err := i.decodeBase64(b64encrypted)
if err != nil {
return nil, err
}
decrypted, err := rsa.DecryptOAEP(sha1.New(), nil, i.key, encrypted, label)
if err != nil {
return nil, err
}
return decrypted, nil
}
func (i *info) rsaKeyParseIv(iv string) ([]byte, error) {
dec, err := i.decodeBase64(iv)
if err != nil {
return nil, err
}
return dec, nil
}