Added explanation of server auth and started authentication tests

This commit is contained in:
Kevin F 2022-09-08 13:33:57 -05:00
parent cb27d192c2
commit 8e5f0ef73f
2 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,98 @@
# Keyboard connection authentication
Keyboarding obviously has a ton of sensitive data, so we need to both encrypt and
authenticate the connections.
All connections are encrypted using an external TLS proxy (e.g. Caddy) outside the
scope of this project, but we perform application level authentication using two
randomly generated UUIDv4s in a manner similar to a passphrase. @{token generation}
We hash the token using sha3-256 to avoid accidentally exposing the token to a
readonly attacker.
## Generating the authentication token
``` go
--- token generation
id := uuid.New() + uuid.New()
hashedID := sha3.Sum256([]byte(id))
---
```
## Storing the authentication token
We then store the token in a file, which is set
by the environment variable `KEYBOARD_AUTH_TOKEN_FILE`, but defaults to
'XDG_CONFIG_HOME/smartkeyboard/auth-token.' @{defineProvisionTokenFile}
``` go
--- store token
if err := os.WriteFile(KEYBOARD_AUTH_TOKEN_FILE, hashedID, 0666); err != nil {
log.Fatal(err)
}
---
```
## Checking authentication
When a client connects, the [websocket server](Server.md) checks the token they send against the stored token.
``` go
--- check token
func checkAuthToken(token string) error {
hashedToken := sha3.Sum256([]byte(token))
storedToken, err := os.ReadFile(KEYBOARD_AUTH_TOKEN_FILE)
if err != nil {
return err
}
if subtle.ConstantTimeCompare(hashedToken[:], storedToken) != 1 {
return errors.New("invalid token")
}
return nil
}
---
```
--- /auth/auth.go
package main
@{auth imports}
@{check token}
---
--- auth imports
import(
//"github.com/google/uuid"
//"encoding/base64"
"golang.org/x/crypto/sha3"
"os"
"errors"
"crypto/subtle"
)
---
``` go
--- defineProvisionTokenFile
provisionTokenFile, keyboardAuthExists := os.Getenv("KEYBOARD_AUTH_TOKEN_FILE")
if keyboardAuthExists == false {
provisionTokenFile = filepath.Join(xdg.ConfigHome, "smartkeyboard", "auth-token")
}
---
```
```go
--- provisionToken
func provisionToken() (error){
@{defineProvisionTokenFile}
@{token generation}
@{store token}
}
---
```

View File

@ -0,0 +1,16 @@
package main
import (
"testing"
)
func TestAuthPasswordHashBad(t *testing.T) {
t.Log("TestAuthPasswordHash")
expectedResult := error(nil) // OK
password := "wrong password"
result := checkAuthToken(password)
if result != expectedResult {
t.Errorf("Expected %s, got %s", expectedResult, result)
}
}