-
Notifications
You must be signed in to change notification settings - Fork 0
/
registry.go
128 lines (109 loc) · 3.3 KB
/
registry.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
package registry
import (
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"golang.org/x/crypto/nacl/secretbox"
)
type Reservation struct {
Username string `json:"username"`
Password string `json:"password"`
ReserveDate time.Time `json:"reserveDate"`
ReserveCourt string `json:"reserveCourt"`
ReserveTime string `json:"reserveTime"`
}
type Registry struct {
Bucket string
Dirname string
Filename string
Content []byte
}
// CreateRegistryFile create temporary file in /tmp directory
// with content of Registry.Content
func (r *Registry) CreateRegistryFile(key string) {
f, err := os.Create(fmt.Sprintf("/tmp/%s", r.Filename))
if err != nil {
panic(err)
}
defer f.Close()
encryptedContent := r.sealFile(key)
f.Write(encryptedContent)
}
// UploadRegistryFile upload the file (created by CreateRegistryFile method)
// to S3 at path s3://Bucket/Dirname/Filename
func (r *Registry) UploadRegistryFile(sess *session.Session) {
f, err := os.Open(fmt.Sprintf("/tmp/%s", r.Filename))
if err != nil {
panic(err)
}
defer f.Close()
uploader := s3manager.NewUploader(sess)
_, err = uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(r.Bucket),
Key: aws.String(fmt.Sprintf("%s/%s", r.Dirname, r.Filename)),
Body: f,
ContentType: aws.String("application/json"),
})
if err != nil {
fmt.Printf("Unable to upload %v to %q, %v", f, r.Bucket, err)
return
}
fmt.Printf("Successfully uploaded %v to %q\n", f, r.Bucket)
}
// FetchRegistryFile read content from s3 file and store content into Registry r
func (r *Registry) FetchRegistryFile(sess *session.Session, key string) error {
buf := aws.NewWriteAtBuffer([]byte{})
downloader := s3manager.NewDownloader(sess)
filepath := fmt.Sprintf("%s/%s", r.Dirname, r.Filename)
_, err := downloader.Download(buf, &s3.GetObjectInput{
Bucket: aws.String(r.Bucket),
Key: aws.String(filepath),
})
if err != nil {
fmt.Printf("Unable to fetch file %s from bucket %s\n", filepath, r.Bucket)
return errors.New("s3 fetch file error")
}
fmt.Printf("Successfully fetch file %s from bucket %s\n", filepath, r.Bucket)
r.openFile(buf.Bytes(), key)
return nil
}
// sealFile encrypt Registry.Content with provided 32 bytes hexKey
// and return the encrypted result
func (r *Registry) sealFile(hexKey string) []byte {
secretKeyBytes, err := hex.DecodeString(hexKey)
if err != nil {
panic(err)
}
var secretKey [32]byte
copy(secretKey[:], secretKeyBytes)
var nonce [24]byte
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
panic(err)
}
return secretbox.Seal(nonce[:], r.Content, &nonce, &secretKey)
}
// openFile decrypt given encrypted input with 32 byte hexKey and assigned decrypted
// value to Registry.Content
func (r *Registry) openFile(encrypted []byte, hexKey string) {
secretKeyBytes, err := hex.DecodeString(hexKey)
if err != nil {
panic(err)
}
var secretKey [32]byte
copy(secretKey[:], secretKeyBytes)
var decryptNonce [24]byte
copy(decryptNonce[:], encrypted[:24])
decrypted, ok := secretbox.Open(nil, encrypted[24:], &decryptNonce, &secretKey)
if !ok {
panic("decryption error")
}
r.Content = decrypted
}