register, register device and get devices working.

This commit is contained in:
Mariano Uvalle 2023-11-08 07:33:19 +00:00
parent a8b497d426
commit 320dc46010
14 changed files with 405 additions and 65 deletions

View file

@ -0,0 +1,131 @@
package client
import (
"bytes"
"crypto/ecdh"
"encoding/json"
"errors"
"io"
"log"
"net/http"
"time"
"github.com/AYM1607/ccclip/internal/server"
"github.com/AYM1607/ccclip/pkg/crypto"
)
type Client struct {
url string
}
func New(url string) *Client {
return &Client{
url: url,
}
}
func (c *Client) Register(email, password string) error {
req := server.RegisterRequest{
Email: email,
Password: password,
}
reqJson, err := json.Marshal(req)
if err != nil {
return err
}
res, err := http.Post(c.url+"/register", "application/json", bytes.NewReader(reqJson))
if err != nil {
return err
}
if res.StatusCode != http.StatusCreated {
return errors.New("got unexpected response code from server")
}
resBody, err := io.ReadAll(res.Body)
defer res.Body.Close()
if err != nil {
return err
}
log.Println(string(resBody))
return nil
}
func (c *Client) RegisterDevice(email, password string, devicePublicKey []byte) (*server.RegisterDeviceResponse, error) {
req := server.RegisterDeviceRequest{
Email: email,
Password: password,
PublicKey: devicePublicKey,
}
reqJson, err := json.Marshal(req)
if err != nil {
return nil, err
}
hres, err := http.Post(c.url+"/registerDevice", "application/json", bytes.NewReader(reqJson))
if err != nil {
return nil, err
}
if hres.StatusCode != http.StatusCreated {
return nil, errors.New("got unexpected response code from server")
}
hresBody, err := io.ReadAll(hres.Body)
defer hres.Body.Close()
if err != nil {
return nil, err
}
log.Println(string(hresBody))
var res server.RegisterDeviceResponse
err = json.Unmarshal(hresBody, &res)
if err != nil {
return nil, err
}
return &res, nil
}
func (c *Client) GetDevices(deviceId string, pvk *ecdh.PrivateKey) (*server.GetUserDevicesResponse, error) {
req := server.GetUserDevicesRequest{
FingerPrint: server.FingerPrint{Timestamp: time.Now().UTC()},
}
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
key := crypto.NewSharedKey(pvk, serverPublicKey, crypto.SendDirection)
encryptedReq := crypto.Encrypt(key, reqBytes)
authReq := server.AuthenticatedPayload{
DeviceID: deviceId,
Payload: encryptedReq,
}
authReqJson, err := json.Marshal(authReq)
if err != nil {
return nil, err
}
hres, err := http.Post(c.url+"/userDevices", "application/json", bytes.NewReader(authReqJson))
if err != nil {
return nil, err
}
hresBody, err := io.ReadAll(hres.Body)
defer hres.Body.Close()
if err != nil {
return nil, err
}
log.Println(string(hresBody))
if hres.StatusCode != http.StatusOK {
return nil, errors.New("got unexpected response code from server")
}
var res server.GetUserDevicesResponse
err = json.Unmarshal(hresBody, &res)
if err != nil {
return nil, err
}
return &res, nil
}

View file

@ -0,0 +1,22 @@
package client
import (
"crypto/ecdh"
"encoding/base64"
"fmt"
"github.com/AYM1607/ccclip/pkg/crypto"
)
const serverPublicKeyB64 = "JTyaIVDHe1Nwqmd4NFlkvqj+MZOVp5s3JZP+T3QuoT8="
var serverPublicKey *ecdh.PublicKey
func init() {
pkeyBytes := make([]byte, crypto.KeySize)
_, err := base64.StdEncoding.Decode(pkeyBytes, []byte(serverPublicKeyB64))
if err != nil {
panic(fmt.Sprintf("cannot decode server public key: %s", err.Error()))
}
serverPublicKey = crypto.PublicKeyFromBytes(pkeyBytes)
}

View file

@ -3,6 +3,7 @@ package server
import (
"crypto/ecdh"
"encoding/json"
"reflect"
"time"
"github.com/AYM1607/ccclip/internal/db"
@ -22,6 +23,11 @@ func decryptAuthenticatedPayload[T any](p AuthenticatedPayload, d db.DB, pk *ecd
var res T
var zero T
_T := reflect.TypeOf(res)
if _T.Kind() == reflect.Pointer {
res = reflect.New(_T.Elem()).Interface().(T)
}
device, err := d.GetDevice(p.DeviceID)
if err != nil {
return zero, err

View file

@ -33,10 +33,18 @@ type controller struct {
func newHttpHandler() http.Handler {
r := mux.NewRouter()
pbk, err := crypto.LoadPublicKey(config.Default.PublicKeyPath)
if err != nil {
panic("could not load server's public key")
}
pvk, err := crypto.LoadPrivateKey(config.Default.PrivateKeyPath)
if err != nil {
panic("could not load server's private key")
}
c := &controller{
store: db.NewLocalDB(),
publicKey: crypto.LoadPublicKey(config.Default.PublicKeyPath),
privateKey: crypto.LoadPrivateKey(config.Default.PrivateKeyPath),
publicKey: pbk,
privateKey: pvk,
}
// TODO: These are not restful at all, but it's the simplest for now. FIX IT!