gosmartkeyboard/security/Authentication.md

98 lines
2.1 KiB
Markdown
Raw Normal View History

# 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}
}
---
```