mirror of
https://github.com/cloudflare/redoctober.git
synced 2026-01-08 15:21:50 +00:00
Merge pull request #27 from grittygrease/server-reload-fix
Add support for unmarshalling ECC passvault
This commit is contained in:
@@ -9,11 +9,11 @@ encryption and decryption server.
|
||||
|
||||
[](https://travis-ci.org/cloudflare/redoctober) [](https://drone.io/github.com/cloudflare/redoctober/latest)
|
||||
|
||||
This project requires [Go 1.1](http://golang.org/doc/install#download)
|
||||
This project requires [Go 1.2](http://golang.org/doc/install#download)
|
||||
or later to compile. Verify your go version by running `go version`:
|
||||
|
||||
$ go version
|
||||
go version go1.1
|
||||
go version go1.2
|
||||
|
||||
As with any Go program you do need to set the
|
||||
[GOPATH enviroment variable](http://golang.org/doc/code.html#GOPATH)
|
||||
@@ -35,7 +35,7 @@ secure) way is to skip the
|
||||
[Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority#Issuing_a_certificate)
|
||||
verification and generate a self-signed TLS certificate. Read this
|
||||
[detailed guide](http://www.akadia.com/services/ssh_test_certificate.html)
|
||||
or, alternatively, follow this unsecure commands:
|
||||
or, alternatively, follow these unsecure commands:
|
||||
|
||||
$ mkdir cert
|
||||
$ chmod 700 cert
|
||||
|
||||
@@ -28,7 +28,7 @@ func zero(in []byte) {
|
||||
|
||||
// Encrypt secures and authenticates its input using the public key
|
||||
// using ECDHE with AES-128-CBC-HMAC-SHA1.
|
||||
func Encrypt(pub ecdsa.PublicKey, in []byte) (out []byte, err error) {
|
||||
func Encrypt(pub *ecdsa.PublicKey, in []byte) (out []byte, err error) {
|
||||
ephemeral, err := ecdsa.GenerateKey(Curve(), rand.Reader)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestGenerateKey(t *testing.T) {
|
||||
|
||||
func TestCrypt(t *testing.T) {
|
||||
message := []byte("One ping only, please.")
|
||||
out, err := Encrypt(testKey.PublicKey, message)
|
||||
out, err := Encrypt(&testKey.PublicKey, message)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
@@ -50,6 +50,22 @@ const (
|
||||
// Path of current vault
|
||||
var localPath string
|
||||
|
||||
type ECPublicKey struct {
|
||||
Curve *elliptic.CurveParams
|
||||
X, Y *big.Int
|
||||
}
|
||||
|
||||
// toECDSA takes the internal ECPublicKey and returns an equivalent
|
||||
// an ecdsa.PublicKey
|
||||
func (pk *ECPublicKey) toECDSA() *ecdsa.PublicKey {
|
||||
ecdsaPub := new(ecdsa.PublicKey)
|
||||
ecdsaPub.Curve = pk.Curve
|
||||
ecdsaPub.X = pk.X
|
||||
ecdsaPub.Y = pk.Y
|
||||
|
||||
return ecdsaPub
|
||||
}
|
||||
|
||||
// PasswordRecord is the structure used to store password and key
|
||||
// material for a single user name. It is written and read from
|
||||
// storage in JSON format.
|
||||
@@ -71,7 +87,7 @@ type PasswordRecord struct {
|
||||
ECKey struct {
|
||||
ECPriv []byte
|
||||
ECPrivIV []byte
|
||||
ECPublic ecdsa.PublicKey
|
||||
ECPublic ECPublicKey
|
||||
}
|
||||
Admin bool
|
||||
}
|
||||
@@ -200,7 +216,9 @@ func createPasswordRec(password string, admin bool) (newRec PasswordRecord, err
|
||||
if err = encryptECCRecord(&newRec, ecPriv, passKey); err != nil {
|
||||
return
|
||||
}
|
||||
newRec.ECKey.ECPublic = ecPriv.PublicKey
|
||||
newRec.ECKey.ECPublic.Curve = ecPriv.PublicKey.Curve.Params()
|
||||
newRec.ECKey.ECPublic.X = ecPriv.PublicKey.X
|
||||
newRec.ECKey.ECPublic.Y = ecPriv.PublicKey.Y
|
||||
}
|
||||
|
||||
// encrypt AES key with password key
|
||||
@@ -530,7 +548,7 @@ func (pr PasswordRecord) EncryptKey(in []byte) (out []byte, err error) {
|
||||
if pr.Type == RSARecord {
|
||||
return rsa.EncryptOAEP(sha1.New(), rand.Reader, &pr.RSAKey.RSAPublic, in, nil)
|
||||
} else if pr.Type == ECCRecord {
|
||||
return ecdh.Encrypt(pr.ECKey.ECPublic, in)
|
||||
return ecdh.Encrypt(pr.ECKey.ECPublic.toECDSA(), in)
|
||||
} else {
|
||||
return nil, errors.New("Invalid function for record type")
|
||||
}
|
||||
@@ -568,7 +586,7 @@ func (pr PasswordRecord) GetKeyECCPub() (out *ecdsa.PublicKey, err error) {
|
||||
if pr.Type != ECCRecord {
|
||||
return out, errors.New("Invalid function for record type")
|
||||
}
|
||||
return &pr.ECKey.ECPublic, err
|
||||
return pr.ECKey.ECPublic.toECDSA(), err
|
||||
}
|
||||
|
||||
// GetKeyECC returns the ECDSA private key of the record given the correct password.
|
||||
|
||||
@@ -6,8 +6,26 @@ package passvault
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"os"
|
||||
)
|
||||
|
||||
func TestStaticVault(t *testing.T) {
|
||||
err := InitFromDisk("/tmp/redoctober.json")
|
||||
if err != nil {
|
||||
t.Fatalf("Error reading record", err)
|
||||
}
|
||||
|
||||
_, err = AddNewRecord("test", "bad pass", true)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating record", err)
|
||||
}
|
||||
err = InitFromDisk("/tmp/redoctober.json")
|
||||
if err != nil {
|
||||
t.Fatalf("Error reading record", err)
|
||||
}
|
||||
os.Remove("/tmp/redoctober.json")
|
||||
}
|
||||
|
||||
func TestRSAEncryptDecrypt(t *testing.T) {
|
||||
oldDefaultRecordType := DefaultRecordType
|
||||
DefaultRecordType = RSARecord
|
||||
|
||||
Reference in New Issue
Block a user