Skip to content

Commit

Permalink
feat: make it usable as a lib (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
supercaracal authored Feb 9, 2024
1 parent 1d19203 commit 9cea50b
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 59 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ jobs:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
cache: true

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
args: release --rm-dist
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6 changes: 3 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ jobs:
run: sudo apt update && sudo apt install -y --no-install-recommends postgresql-client

- name: Check out code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
Expand All @@ -68,7 +68,7 @@ jobs:
run: |
echo -n "CREATE ROLE test WITH LOGIN PASSWORD " >> $SQL_FILE_PATH
echo -n "'" >> $SQL_FILE_PATH
./encrypt test | tr -d '\n' >> $SQL_FILE_PATH
./cmd/tool/encrypt test | tr -d '\n' >> $SQL_FILE_PATH
echo "';" >> $SQL_FILE_PATH
cat $SQL_FILE_PATH | tee /dev/stderr | psql
env:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
encrypt
/cmd/tool/encrypt
3 changes: 1 addition & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ builds:
goarm:
- 6
- 7
main: ./cmd/tool

# https://goreleaser.com/customization/archive/
archives:
- name_template: '{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}{{ with .Arm }}-v{{ . }}{{ end }}'
format: binary
replacements:
amd64: x86_64
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
CGO_ENABLED ?= $(shell go env CGO_ENABLED)

encrypt: main.go
GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=${CGO_ENABLED} go build -ldflags="-s -w" -trimpath -o $@
cmd/tool/encrypt: cmd/tool/main.go
GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=${CGO_ENABLED} go build -ldflags="-s -w" -trimpath -o $@ $^

.PHONY: cmd/tool/encrypt
54 changes: 54 additions & 0 deletions cmd/tool/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

// @see https://github.com/postgres/postgres/blob/c30f54ad732ca5c8762bb68bbe0f51de9137dd72/src/interfaces/libpq/fe-auth.c#L1167-L1285
// @see https://github.com/postgres/postgres/blob/e6bdfd9700ebfc7df811c97c2fc46d7e94e329a2/src/interfaces/libpq/fe-auth-scram.c#L868-L905
// @see https://github.com/postgres/postgres/blob/c30f54ad732ca5c8762bb68bbe0f51de9137dd72/src/port/pg_strong_random.c#L66-L96
// @see https://github.com/postgres/postgres/blob/e6bdfd9700ebfc7df811c97c2fc46d7e94e329a2/src/common/scram-common.c#L160-L274
// @see https://github.com/postgres/postgres/blob/e6bdfd9700ebfc7df811c97c2fc46d7e94e329a2/src/common/scram-common.c#L27-L85

import (
"fmt"
"os"
"syscall"

"github.com/supercaracal/scram-sha-256/pkg/pgpasswd"
"golang.org/x/crypto/ssh/terminal"
)

func readRawPassword(fd int) ([]byte, error) {
input, err := terminal.ReadPassword(fd)
if err != nil {
return nil, err
}
return input, nil
}

func main() {
var rawPassword []byte

if len(os.Args) > 1 {
rawPassword = []byte(os.Args[1])
} else {
fmt.Print("Raw password: ")
passwd, err := readRawPassword(int(syscall.Stdin))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rawPassword = passwd
fmt.Println()
}

if len(rawPassword) == 0 {
fmt.Println("empty password")
os.Exit(1)
}

if password, err := pgpasswd.Encrypt(rawPassword); err != nil {
fmt.Println(err)
os.Exit(1)
} else {
fmt.Printf("%s\n", password)
os.Exit(0)
}
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module github.com/supercaracal/scram-sha-256

go 1.19

require golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
require golang.org/x/crypto v0.19.0

require (
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.17.0 // indirect
)
13 changes: 6 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
42 changes: 5 additions & 37 deletions main.go → pkg/pgpasswd/crypto.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package pgpasswd

// @see https://github.com/postgres/postgres/blob/c30f54ad732ca5c8762bb68bbe0f51de9137dd72/src/interfaces/libpq/fe-auth.c#L1167-L1285
// @see https://github.com/postgres/postgres/blob/e6bdfd9700ebfc7df811c97c2fc46d7e94e329a2/src/interfaces/libpq/fe-auth-scram.c#L868-L905
Expand All @@ -13,11 +13,8 @@ import (
"encoding/base64"
"fmt"
"io"
"os"
"syscall"

"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/ssh/terminal"
)

const (
Expand All @@ -44,14 +41,6 @@ func genSalt(size int) ([]byte, error) {
return salt, nil
}

func readRawPassword(fd int) ([]byte, error) {
input, err := terminal.ReadPassword(fd)
if err != nil {
return nil, err
}
return input, nil
}

func encodeB64(src []byte) (dst []byte) {
dst = make([]byte, base64.StdEncoding.EncodedLen(len(src)))
base64.StdEncoding.Encode(dst, src)
Expand Down Expand Up @@ -84,33 +73,12 @@ func encryptPassword(rawPassword, salt []byte, iter, keyLen int) string {
)
}

func main() {
var rawPassword []byte

if len(os.Args) > 1 {
rawPassword = []byte(os.Args[1])
} else {
fmt.Print("Raw password: ")
passwd, err := readRawPassword(int(syscall.Stdin))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rawPassword = passwd
fmt.Println()
}

if len(rawPassword) == 0 {
fmt.Println("empty password")
os.Exit(1)
}

// Encrypt encrypts a raw password with scram-sha-256
func Encrypt(rawPassword []byte) (string, error) {
salt, err := genSalt(saltSize)
if err != nil {
fmt.Println(err)
os.Exit(1)
return "", err
}

fmt.Printf("%s\n", encryptPassword(rawPassword, salt, iterationCnt, digestLen))
os.Exit(0)
return encryptPassword(rawPassword, salt, iterationCnt, digestLen), nil
}

0 comments on commit 9cea50b

Please sign in to comment.