Skip to content

Commit

Permalink
Added LUKS2 support (#56)
Browse files Browse the repository at this point in the history
* Added LUKS2 support

* Modified test for LUKS1 with new arg

* finangling tests

* More test finangling. Added luksVersion param to test functions.

* forgot cmd+s

Co-authored-by: skim-milk <[email protected]>
Co-authored-by: Derek <[email protected]>
  • Loading branch information
3 people authored Feb 21, 2021
1 parent 894f90f commit e1dcdbe
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 45 deletions.
21 changes: 15 additions & 6 deletions cmd/luks2crypt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ func run(args []string) error {
Usage: "Luks Device to rotate password on. Ex. /dev/sda3"},
cli.StringFlag{Name: "currentpassword, p",
Usage: "Password to unlock and update device"},
cli.IntFlag{Name: "luksVersion, v",
Usage: "Luks version",
Value: 2},
cli.StringFlag{Name: "cryptserver, s",
Usage: "Crypt Server to escrow recovery key to. Ex. cryptserver.example.com"},
cli.StringFlag{Name: "cryptendpoint, e",
Expand All @@ -71,13 +74,19 @@ func optVersion(c *cli.Context) error {
func optPostImaging(c *cli.Context) error {
cryptURL := "https://" + c.String("cryptserver")
opts := postimaging.Opts{
LuksDev: c.String("luksdevice"),
CurPass: c.String("currentpassword"),
Server: cryptURL,
URI: c.String("cryptendpoint"),
AuthUser: c.String("authuser"),
AuthPass: c.String("authpass"),
LuksDev: c.String("luksdevice"),
CurPass: c.String("currentpassword"),
Server: cryptURL,
URI: c.String("cryptendpoint"),
AuthUser: c.String("authuser"),
AuthPass: c.String("authpass"),
LuksVersion: c.Int("luksVersion"),
}

if opts.LuksVersion != 1 {
opts.LuksVersion = 2
}

if (opts.AuthUser != "") && (opts.AuthPass == "") {
fmt.Printf("Password: ")
password, err := terminal.ReadPassword(0)
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ go 1.14
require (
github.com/diskfs/go-diskfs v0.0.0-20190517155712-1190dcf1ff31
github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910
github.com/gorilla/schema v1.1.0
github.com/gorilla/schema v1.2.0
github.com/kr/pretty v0.1.0 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sethvargo/go-diceware v0.2.0
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/urfave/cli.v1 v1.20.0
)
19 changes: 12 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ github.com/diskfs/go-diskfs v0.0.0-20190517155712-1190dcf1ff31 h1:k5UxaYj85BdnZn
github.com/diskfs/go-diskfs v0.0.0-20190517155712-1190dcf1ff31/go.mod h1:/Law/HCWU7AOPxin1Tg4L9eUwlLjVUsuztx/s4X683E=
github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910 h1:w9T/rS5VP0SPXqYr7BpUeqf6ukp/GEWm6nXhziWzBY4=
github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910/go.mod h1:yGxJ4za56u74+F00gmg9RJoyXLzvrOrIat4b/Dgw9Lo=
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand All @@ -14,13 +14,18 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
github.com/sethvargo/go-diceware v0.2.0 h1:3QzXGqUe0UR9y1XYSz1dxGS+fKtXOxRqqKjy+cG1yTI=
github.com/sethvargo/go-diceware v0.2.0/go.mod h1:II+37A5sTGAtg3zd/JqyVQ8qqAjSm/2r2X6qkVZDjyg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
38 changes: 23 additions & 15 deletions internal/luks/luks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Settings struct {
OldPass, NewPass, LuksDevice string
LuksSlot int
cDevice *C.struct_crypt_device
LuksVersion int
}

// Error holds error messages from this package
Expand Down Expand Up @@ -52,7 +53,11 @@ func (luksDevice *Settings) cryptInit() (*C.struct_crypt_device, error) {

// load populates the libcryptsetup struct with device info from disk
func (luksDevice *Settings) load() error {
cCryptType := C.CString(C.CRYPT_LUKS1)
cCryptType := C.CString(C.CRYPT_LUKS2)
if luksDevice.LuksVersion == 1 {
cCryptType = C.CString(C.CRYPT_LUKS1)
}

defer C.free(unsafe.Pointer(cCryptType))

err := C.crypt_load(luksDevice.cDevice, cCryptType, nil)
Expand Down Expand Up @@ -141,7 +146,11 @@ func (luksDevice *Settings) format() (int, error) {
data_device: nil,
}

cLuksType := C.CString(C.CRYPT_LUKS1)
cLuksType := C.CString(C.CRYPT_LUKS2)
if luksDevice.LuksVersion == 1 {
cLuksType = C.CString(C.CRYPT_LUKS1)
}

defer C.free(unsafe.Pointer(cLuksType))

cLuksCipher := C.CString("aes")
Expand Down Expand Up @@ -207,10 +216,11 @@ func (luksDevice *Settings) freeCryptDev() {

// formatSetPassword formats a device with luks and adds a passphrase to device
// This is used by tests to create a virtual disk
func formatSetPassword(pass string, luksDevice string) (bool, error) {
func formatSetPassword(pass string, luksDevice string, luksVersion int) (bool, error) {
cryptInfo := &Settings{
NewPass: pass,
LuksDevice: luksDevice,
NewPass: pass,
LuksDevice: luksDevice,
LuksVersion: luksVersion,
}

cCryptDev, err := cryptInfo.cryptInit()
Expand All @@ -233,9 +243,10 @@ func formatSetPassword(pass string, luksDevice string) (bool, error) {
}

// PassWorks tests if a luks password is correct
func PassWorks(pass string, luksDevice string) (bool, error) {
func PassWorks(pass string, luksDevice string, luksVersion int) (bool, error) {
cryptInfo := &Settings{
LuksDevice: luksDevice,
LuksDevice: luksDevice,
LuksVersion: luksVersion,
}

cCryptDev, err := cryptInfo.cryptInit()
Expand All @@ -261,15 +272,12 @@ func PassWorks(pass string, luksDevice string) (bool, error) {
}

// SetRecoveryPassword changes the luks passphrase on the device
func SetRecoveryPassword(
oldPass string,
newPass string,
luksDevice string,
) error {
func SetRecoveryPassword(oldPass string, newPass string, luksDevice string, luksVersion int) error {
cryptInfo := &Settings{
OldPass: oldPass,
NewPass: newPass,
LuksDevice: luksDevice,
OldPass: oldPass,
NewPass: newPass,
LuksDevice: luksDevice,
LuksVersion: luksVersion,
}

cCryptDev, err := cryptInfo.cryptInit()
Expand Down
28 changes: 16 additions & 12 deletions internal/luks/luks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
type testDisk struct {
path, pass, newPass string
size int64
luksVersion int
}

// createTempDir allocates a temporary directory in the system $TMPDIR
Expand All @@ -36,8 +37,9 @@ func createTempDir(t *testing.T, dir string, prefix string) string {
// create allocates and formats a disk to run tests against
func (d testDisk) create(t *testing.T) {
luksDev := &Settings{
NewPass: d.pass,
LuksDevice: d.path,
NewPass: d.pass,
LuksDevice: d.path,
LuksVersion: d.luksVersion,
}

disk, err := diskfs.Create(d.path, d.size, diskfs.Raw)
Expand All @@ -55,7 +57,7 @@ func (d testDisk) create(t *testing.T) {
t.Errorf("error partitioning test filesystem %v", err)
}

_, err = formatSetPassword(luksDev.NewPass, luksDev.LuksDevice)
_, err = formatSetPassword(luksDev.NewPass, luksDev.LuksDevice, luksDev.LuksVersion)
if err != nil {
t.Errorf("error creating test luks device: %v", err)
}
Expand All @@ -66,13 +68,14 @@ func TestPassWorks(t *testing.T) {
defer os.RemoveAll(dir)

expected := testDisk{
path: path.Clean(dir + "/luksdisk.img"),
size: int64(10 * 1024 * 1024), // 10MB
pass: "testPassw0rd!",
path: path.Clean(dir + "/luksdisk.img"),
size: int64(10 * 1024 * 1024), // 10MB
pass: "testPassw0rd!",
luksVersion: 1,
}
expected.create(t)

_, err := PassWorks(expected.pass, expected.path)
_, err := PassWorks(expected.pass, expected.path, expected.luksVersion)
if err != nil {
t.Errorf("error checking if '%v' is the password for '%v'. Got %v",
expected.pass,
Expand All @@ -87,14 +90,15 @@ func TestSetRecoveryPassword(t *testing.T) {
defer os.RemoveAll(dir)

expected := testDisk{
path: path.Clean(dir + "/luksdisk.img"),
size: int64(10 * 1024 * 1024), // 10MB
pass: "testPassw0rd!",
newPass: "Th!sIsTh3NewPassw0d*",
path: path.Clean(dir + "/luksdisk.img"),
size: int64(10 * 1024 * 1024), // 10MB
pass: "testPassw0rd!",
newPass: "Th!sIsTh3NewPassw0d*",
luksVersion: 1,
}
expected.create(t)

err := SetRecoveryPassword(expected.pass, expected.newPass, expected.path)
err := SetRecoveryPassword(expected.pass, expected.newPass, expected.path, expected.luksVersion)
if err != nil {
t.Errorf("error changing password from '%v' to '%v' on '%v'. Got %v",
expected.pass,
Expand Down
5 changes: 3 additions & 2 deletions pkg/postimaging/postimaging.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

// Opts is used to store the options needed for postimaging functions
type Opts struct {
LuksVersion int
LuksDev, CurPass, Server, URI, AuthUser, AuthPass string
}

Expand Down Expand Up @@ -52,7 +53,7 @@ func Run(opts Opts) error {
log.Println("generated new random password")

// test if the current password works before performing destructive actions
passWorks, err := luks.PassWorks(opts.CurPass, opts.LuksDev)
passWorks, err := luks.PassWorks(opts.CurPass, opts.LuksDev, opts.LuksVersion)
if err != nil || passWorks == false {
return err
}
Expand Down Expand Up @@ -84,7 +85,7 @@ func Run(opts Opts) error {

// change luks admin password to new password
err = luks.SetRecoveryPassword(opts.CurPass, cryptServerData.Pass,
opts.LuksDev)
opts.LuksDev, opts.LuksVersion)
if err != nil {
return err
}
Expand Down

0 comments on commit e1dcdbe

Please sign in to comment.