diff options
| author | Andrew <saintruler@gmail.com> | 2021-04-28 20:31:16 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2021-04-28 20:31:16 +0400 |
| commit | 8ebbdab5079f803567297af842c87ce012b7ea11 (patch) | |
| tree | ffe28a45797dab60b036eb05e419532cae329171 /http-server | |
| parent | 7d6270f64b1dc00d91230b5c793bc49991f0fcf8 (diff) | |
Added cryptography functions and completed client and server.
Diffstat (limited to 'http-server')
| -rw-r--r-- | http-server/cryptography.go | 49 | ||||
| -rw-r--r-- | http-server/main.go | 47 |
2 files changed, 69 insertions, 27 deletions
diff --git a/http-server/cryptography.go b/http-server/cryptography.go new file mode 100644 index 0000000..3340446 --- /dev/null +++ b/http-server/cryptography.go @@ -0,0 +1,49 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "errors" + "fmt" +) + +func decodeMessage(ciphertext []byte, stringKey string) ([]byte, error) { + block, _ := pem.Decode([]byte(stringKey)) + if block == nil { + return nil, errors.New("key is not found in given string") + } + + key, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + + plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, key, ciphertext) + if err != nil { + return nil, err + } + return plaintext, err +} + +func checkSignature(req Request, signature string, key string) (bool, error) { + reqBytes, _ := json.Marshal(req) + req64 := base64.StdEncoding.EncodeToString(reqBytes) + h := sha256.Sum256([]byte(req64)) + requestHash := fmt.Sprintf("%x", h) + + decodedSign, err := base64.StdEncoding.DecodeString(signature) + if err != nil { + return false, err + } + signHash, err := decodeMessage(decodedSign, key) + if err != nil { + return false, err + } + + return requestHash == string(signHash), nil +} diff --git a/http-server/main.go b/http-server/main.go index f77c32f..d7b2625 100644 --- a/http-server/main.go +++ b/http-server/main.go @@ -1,7 +1,6 @@ package main import ( - "crypto/sha256" "encoding/base64" "encoding/json" "errors" @@ -14,8 +13,6 @@ import ( "time" ) -const TimestampFormat = "2006-01-02T15-01-05.999" - type Response struct { Message string } @@ -116,8 +113,8 @@ func register(w http.ResponseWriter, r *http.Request) { return } - // TODO(andrew): Добавить проверку действительности ключа - if false { + checkResult, err := checkSignature(req, signature, req.Data) + if err != nil || !checkResult { w.WriteHeader(http.StatusBadRequest) _ = jsonResponse(w, Response{ Message: "Указанный ключ не является действительным", @@ -139,32 +136,27 @@ func register(w http.ResponseWriter, r *http.Request) { }) } -func handleAuthentication(req Request, signature string) (error, error) { +func handleAuthentication(req Request, signature string) (bool, error) { userRegistered, dbError := db.checkUserRegistered(req.User) if dbError != nil { - return nil, dbError + return false, dbError } if !userRegistered { - return errors.New("такой пользователь не зарегистрирован"), nil + return false, nil } key, err := db.getUserKey(req.User) if err != nil { - return nil, err + return false, err } - // TODO(andrew): Добавить проверку подписи signature - reqBytes, _ := json.Marshal(req) - req64 := base64.StdEncoding.EncodeToString(reqBytes) - h := sha256.Sum256([]byte(req64)) - generatedSignature := fmt.Sprintf("%x", h) - //fmt.Println(generatedSignature) - //fmt.Println(signature) - _ = fmt.Sprint(generatedSignature == signature) - _ = fmt.Sprint(key) + check, err := checkSignature(req, signature, key) + if err != nil { + return false, err + } - return nil, nil + return check, nil } func sendMessage(w http.ResponseWriter, r *http.Request) { @@ -178,8 +170,8 @@ func sendMessage(w http.ResponseWriter, r *http.Request) { return } - authErr, dbErr := handleAuthentication(req, signature) - if authErr != nil { + authComplete, dbErr := handleAuthentication(req, signature) + if !authComplete { w.WriteHeader(http.StatusForbidden) _ = jsonResponse(w, Response{ Message: "Запрос не прошёл аутентификацию", @@ -224,8 +216,8 @@ func pollMessages(w http.ResponseWriter, r *http.Request) { return } - authErr, dbErr := handleAuthentication(req, signature) - if authErr != nil { + authComplete, dbErr := handleAuthentication(req, signature) + if !authComplete { w.WriteHeader(http.StatusForbidden) _ = jsonResponse(w, Response{ Message: "Запрос не прошёл аутентификацию", @@ -273,8 +265,9 @@ func getUserKey(w http.ResponseWriter, r *http.Request) { return } - authErr, dbErr := handleAuthentication(req, signature) - if authErr != nil { + authComplete, dbErr := handleAuthentication(req, signature) + if !authComplete { + w.WriteHeader(http.StatusForbidden) _ = jsonResponse(w, Response{ Message: "Запрос не прошёл аутентификацию", @@ -317,8 +310,8 @@ func tryAuth(w http.ResponseWriter, r *http.Request) { return } - authErr, dbErr := handleAuthentication(req, signature) - if authErr != nil { + authComplete, dbErr := handleAuthentication(req, signature) + if !authComplete { w.WriteHeader(http.StatusForbidden) _ = jsonResponse(w, Response{ Message: "Запрос не прошёл аутентификацию", |