This repository has been archived by the owner on Apr 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
/
server.go
129 lines (111 loc) · 3.79 KB
/
server.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
/* Copyright (c) Edgeless Systems GmbH
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
package server
import (
"crypto/tls"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"github.com/edgelesssys/edgelessdb/edb/core"
"github.com/edgelesssys/edgelessdb/edb/rt"
)
type generalResponse struct {
Status string `json:"status"`
Data interface{} `json:"data"`
Message string `json:"message,omitempty"` // only used when status = "error"
}
type certQuoteResp struct {
Cert string
Quote []byte
}
// CreateServeMux creates a mux that serves the edb API.
func CreateServeMux(core *core.Core) *http.ServeMux {
mux := http.NewServeMux()
mux.HandleFunc("/manifest", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
jsonManifest, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
recoveryKey, err := core.Initialize(jsonManifest)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if recoveryKey != nil {
io.WriteString(w, base64.StdEncoding.EncodeToString(recoveryKey))
}
})
mux.HandleFunc("/signature", func(w http.ResponseWriter, r *http.Request) {
sig := core.GetManifestSignature()
io.WriteString(w, hex.EncodeToString(sig))
})
mux.HandleFunc("/quote", func(w http.ResponseWriter, r *http.Request) {
cert, report, err := core.GetCertificateReport()
if err != nil {
writeJSONError(w, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(w, certQuoteResp{cert, report})
})
mux.HandleFunc("/recover", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
key, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var statusMsg string
if err := core.Recover(r.Context(), key); err != nil {
statusMsg = fmt.Sprintf("Recovery failed: %v", err.Error())
} else {
statusMsg = "Recovery successful."
}
writeJSON(w, statusMsg)
})
return mux
}
// RunServer runs a HTTP server serving mux.
func RunServer(mux *http.ServeMux, address string, tlsConfig *tls.Config) {
server := http.Server{
Addr: address,
Handler: mux,
TLSConfig: tlsConfig,
}
rt.Log.Println("HTTP REST API listening on", address)
rt.Log.Fatalln(server.ListenAndServeTLS("", ""))
}
func writeJSON(w http.ResponseWriter, v interface{}) {
dataToReturn := generalResponse{Status: "success", Data: v}
if err := json.NewEncoder(w).Encode(dataToReturn); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func writeJSONError(w http.ResponseWriter, errorString string, httpErrorCode int) {
marshalledJSON, err := json.Marshal(generalResponse{Status: "error", Message: errorString})
// Only fall back to non-JSON error when we cannot even marshal the error (which is pretty bad)
if err != nil {
http.Error(w, errorString, httpErrorCode)
}
http.Error(w, string(marshalledJSON), httpErrorCode)
}