1 package common
2
3 import (
4 ed "crypto/ed25519"
5 "fmt"
6 "github.com/golang/protobuf/proto"
7 pb "golang.conradwood.net/apis/auth"
8 "io/ioutil"
9 "os"
10 )
11
12 var (
13
14
15 authpubkey = []byte{
16 0x88, 0x8A, 0x3F, 0x33, 0x1F, 0x41, 0xC7, 0x71, 0xDB, 0xC8, 0xF4,
17 0xA0, 0xE8, 0x5C, 0x48, 0xF2, 0xE4, 0xE8, 0xC1, 0xF6, 0x69, 0xE3,
18 0x5A, 0x23, 0x2B, 0x90, 0x38, 0xF6, 0x36, 0xF8, 0xFE, 0x38,
19 }
20 got_pub_key = false
21 authresponse *pb.KeyResponse
22 )
23
24
25 func GetCloudName() string {
26 if authresponse == nil {
27 return ""
28 }
29 return authresponse.CloudName
30 }
31
32
33 func signbytes(in *pb.User) []byte {
34 b := []byte(in.ID)
35 ts := in.SignedAt
36 x := ts
37 for i := 0; i < 4; i++ {
38 b = append(b, byte(x&0xFF))
39 x = x << 8
40 }
41 return b
42 }
43
44
45 func SignAllbytes(in *pb.User) []byte {
46 b := []byte(in.ID)
47 ts := in.SignedAt
48 x := ts
49 for i := 0; i < 4; i++ {
50 b = append(b, byte(x&0xFF))
51 x = x << 8
52 }
53 b = append(b, []byte(in.Email)...)
54 b = append(b, []byte(in.FirstName)...)
55 b = append(b, []byte(in.LastName)...)
56 b = append(b, []byte(in.Abbrev)...)
57 z := byte(0)
58 if in.Active {
59 z = z | 1<<3
60 }
61 if in.ServiceAccount {
62 z = z | 1<<2
63 }
64 if in.EmailVerified {
65 z = z | 1<<1
66 }
67 b = append(b, z)
68 for _, g := range in.Groups {
69 b = append(b, []byte(g.ID)...)
70 }
71 return b
72 }
73
74
79 func VerifySignature(u *pb.User) bool {
80 if u == nil {
81 return false
82 }
83 v := ed.Verify(signPublicKey(), SignAllbytes(u), u.SignatureFull)
84 return v
85 }
86
87 func VerifyBytes(b []byte, signature []byte) bool {
88 v := ed.Verify(signPublicKey(), b, signature)
89 return v
90 }
91
92
93 func VerifySignedUser(u *pb.SignedUser) *pb.User {
94 if u == nil {
95 return nil
96 }
97
98 v := ed.Verify(signPublicKey(), u.User, u.Signature)
99 if !v {
100 return nil
101 }
102 res := &pb.User{}
103 err := proto.Unmarshal(u.User, res)
104 if err != nil {
105 fmt.Printf("[go-easyops] invalid signed user (%s)\n", err)
106 return nil
107 }
108 return res
109 }
110
111 func signPublicKey() ed.PublicKey {
112 if got_pub_key {
113 return authpubkey
114 }
115
116 fname := "/tmp/authkey.pub"
117 _, err := os.Stat(fname)
118 if err == nil {
119 b, err := ioutil.ReadFile(fname)
120 if err != nil {
121 fmt.Printf("[go-easyops] failed to read pubkey file: %s\n", err)
122 } else {
123 fmt.Printf("[go-easyops] read temporary pubkey file: %s\n", fname)
124 authpubkey = b
125 }
126 got_pub_key = true
127 return authpubkey
128 }
129
130 return authpubkey
131 }
132 func SetPublicSigningKey(k *pb.KeyResponse) {
133 got_pub_key = true
134 authpubkey = k.Key
135 authresponse = k
136 }
137 func GetPublicSigningKey() *pb.KeyResponse {
138 return &pb.KeyResponse{Key: signPublicKey()}
139 }
140
View as plain text