Clean up comments and run 'go gmt' across code

This commit is contained in:
John Graham-Cumming
2013-11-19 04:11:38 -08:00
parent 4e1aa78fb8
commit d172058d5d
10 changed files with 199 additions and 177 deletions
+4
View File
@@ -0,0 +1,4 @@
bin/
pkg/
src/code.google.com/
*~
+43 -39
View File
@@ -1,58 +1,59 @@
// Pacakge core handles the main operations of the Red October server.
// Package core handles the main operations of the Red October server.
//
// Copyright (c) 2013 CloudFlare, Inc.
package core
import (
"log"
"errors"
"encoding/json"
"redoctober/passvault"
"errors"
"log"
"redoctober/cryptor"
"redoctober/keycache"
"redoctober/passvault"
)
type credential struct {
Name string
Password string
}
// format of incoming sign-in request
type create struct {
Name string
Password string
credential
}
type summary struct {
Name string
Password string
credential
}
type delegate struct {
Name string
Password string
Uses int
Time string
credential
Uses int
Time string
}
type password struct {
Name string
Password string
credential
NewPassword string
}
type encrypt struct {
Name string
Password string
Minimum int
Owners []string
Data []byte
credential
Minimum int
Owners []string
Data []byte
}
type decrypt struct {
Name string
Password string
Data []byte
credential
Data []byte
}
type modify struct {
Name string
Password string
credential
ToModify string
Command string
Command string
}
// response JSON format
@@ -61,39 +62,39 @@ type status struct {
}
type responseData struct {
Status string
Status string
Response []byte
}
type summaryData struct {
Status string
Live map[string]keycache.ActiveUser
All map[string]passvault.Summary
Live map[string]keycache.ActiveUser
All map[string]passvault.Summary
}
func errToJson(err error) (ret []byte) {
if err == nil {
ret, _ = json.Marshal(status{Status:"ok"})
ret, _ = json.Marshal(status{Status: "ok"})
} else {
ret, _ = json.Marshal(status{Status:err.Error()})
ret, _ = json.Marshal(status{Status: err.Error()})
}
return
}
func summaryToJson(err error) (ret []byte) {
if err == nil {
ret, _ = json.Marshal(summaryData{Status:"ok", Live:keycache.GetSummary(), All:passvault.GetSummary()})
ret, _ = json.Marshal(summaryData{Status: "ok", Live: keycache.GetSummary(), All: passvault.GetSummary()})
} else {
ret, _ = json.Marshal(status{Status:err.Error()})
ret, _ = json.Marshal(status{Status: err.Error()})
}
return
}
func responseToJson(resp []byte, err error) (ret []byte) {
if err == nil {
ret, _ = json.Marshal(responseData{Status:"ok", Response:resp})
ret, _ = json.Marshal(responseData{Status: "ok", Response: resp})
} else {
ret, _ = json.Marshal(status{Status:err.Error()})
ret, _ = json.Marshal(status{Status: err.Error()})
}
return
}
@@ -299,19 +300,22 @@ func Modify(jsonIn []byte) []byte {
return errToJson(errors.New("Cannot modify own record"))
}
switch s.Command {
case "delete": {
case "delete":
{
err = passvault.DeleteRecord(s.ToModify)
}
case "revoke": {
case "revoke":
{
err = passvault.RevokeRecord(s.ToModify)
}
case "admin": {
case "admin":
{
err = passvault.MakeAdmin(s.ToModify)
}
default: {
default:
{
return errToJson(errors.New("Unknown command"))
}
}
return errToJson(err)
}
+8 -7
View File
@@ -1,16 +1,19 @@
// core_test.go: tests for core.go
//
// Copyright (c) 2013 CloudFlare, Inc.
package core
import (
"os"
"encoding/json"
"redoctober/passvault"
"os"
"redoctober/keycache"
"redoctober/passvault"
"redoctober/testing"
)
func TestCreate(t *testing.T) {
createJson := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\"}")
os.Remove("/tmp/db1.json")
Init("/tmp/db1.json")
@@ -138,7 +141,7 @@ func TestSummary(t *testing.T) {
t.Fatalf("Error in summary of account, record missing ")
}
//
//
keycache.FlushCache()
os.Remove("/tmp/db1.json")
@@ -310,9 +313,8 @@ func TestEncryptDecrypt(t *testing.T) {
t.Fatalf("Error in encrypt, ", s.Status)
}
// decrypt file
decryptJson, err := json.Marshal(decrypt{Name:"Alice", Password:"Hello", In:s.Response})
decryptJson, err := json.Marshal(decrypt{Name: "Alice", Password: "Hello", In: s.Response})
if err != nil {
t.Fatalf("Error in marshalling decryption,", err)
}
@@ -527,4 +529,3 @@ func TestModify(t *testing.T) {
os.Remove("/tmp/db1.json")
}
+21 -19
View File
@@ -1,17 +1,21 @@
// Package cryptor encrypts and decrypts files using the Red October vault and key cache.
// Package cryptor encrypts and decrypts files using the Red October
// vault and key cache.
//
// Copyright (c) 2013 CloudFlare, Inc.
package cryptor
import (
"crypto/aes"
"crypto/hmac"
"crypto/sha1"
"crypto/rand"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/sha1"
"encoding/json"
"errors"
"redoctober/passvault"
"redoctober/keycache"
"redoctober/padding"
"redoctober/passvault"
)
const (
@@ -23,25 +27,25 @@ const (
// the names of the users in Name in order.
type MultiWrappedKey struct {
Name []string
Key []byte
Key []byte
}
// SingleWrappedKey is a structure containing
// a 16-byte key encrypted by an RSA key.
type SingleWrappedKey struct {
Key []byte
Key []byte
aesKey []byte
}
// EncryptedFile is the format for encrypted data containing all the keys necessary to
// decrypt it when delegated.
type EncryptedFile struct {
Version int
VaultId int
KeySet []MultiWrappedKey
Version int
VaultId int
KeySet []MultiWrappedKey
KeySetRSA map[string]SingleWrappedKey
IV []byte
Data []byte
IV []byte
Data []byte
Signature []byte
}
@@ -90,7 +94,7 @@ func encryptKey(nameInner, nameOuter string, clearKey []byte, rsaKeys map[string
err = errors.New("Missing user in file")
return
}
overrideOuter, ok = rsaKeys[nameOuter]
if !ok {
err = errors.New("Missing user in file")
@@ -122,7 +126,7 @@ func encryptKey(nameInner, nameOuter string, clearKey []byte, rsaKeys map[string
// decrypt first key in keys whose encryption keys are in keycache
func unwrapKey(keys []MultiWrappedKey, rsaKeys map[string]SingleWrappedKey) (unwrappedKey []byte, err error) {
var (
keyFound error
keyFound error
fullMatch bool = false
)
for _, mwKey := range keys {
@@ -153,7 +157,6 @@ func unwrapKey(keys []MultiWrappedKey, rsaKeys map[string]SingleWrappedKey) (unw
return
}
// Encrypt encrypts data with the keys associated with names
// This requires a minimum of min keys to decrypt.
// NOTE: as currently implemented, the maximum value for min is 2.
@@ -182,14 +185,14 @@ func Encrypt(in []byte, names []string, min int) (resp []byte, err error) {
if err != nil {
return
}
// allocate set of keys to be able to cover all ordered subsets
// of length 2 of names
encrypted.KeySet = make([]MultiWrappedKey, len(names)*(len(names)-1))
// create map to hold RSA encrypted keys
encrypted.KeySetRSA = make(map[string]SingleWrappedKey)
var singleWrappedKey SingleWrappedKey
for _, name := range names {
rec, ok := passvault.GetRecord(name)
@@ -300,7 +303,7 @@ func Decrypt(in []byte) (resp []byte, err error) {
if err != nil {
return
}
// set up the decryption context
aesCrypt, err := aes.NewCipher(unwrappedKey)
if err != nil {
@@ -314,4 +317,3 @@ func Decrypt(in []byte) (resp []byte, err error) {
return padding.RemovePadding(clearData)
}
+10 -8
View File
@@ -1,16 +1,19 @@
// Package keycache provides the ability to hold active keys in memory
// for the Red October server.
//
// Copyright (c) 2013 CloudFlare, Inc.
package keycache
import (
"log"
"time"
"errors"
"crypto/aes"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/rand"
"errors"
"log"
"redoctober/passvault"
"time"
)
// UserKeys is the set of decrypted keys in memory, indexed by name.
@@ -18,10 +21,10 @@ var UserKeys map[string]ActiveUser = make(map[string]ActiveUser)
// ActiveUser holds the information about an actively delegated key
type ActiveUser struct {
Admin bool
Type string
Admin bool
Type string
Expiry time.Time
Uses int
Uses int
// non-public members
aesKey []byte
rsaKey rsa.PrivateKey
@@ -184,4 +187,3 @@ func DecryptKey(in []byte, name string, rsaEncryptedKey []byte) (out []byte, err
return
}
+10 -9
View File
@@ -1,9 +1,12 @@
// keycache_test.go: tests for keycache.go
//
// Copyright (c) 2013 CloudFlare, Inc.
package keycache
import (
"passvault"
"time"
"testing"
"time"
)
var now = time.Now()
@@ -13,10 +16,10 @@ var dummy = make([]byte, 16)
func TestUsesFlush(t *testing.T) {
singleUse := ActiveUser{
Admin: true,
Type: passvault.AESRecord,
Admin: true,
Type: passvault.AESRecord,
Expiry: nextYear,
Uses: 2,
Uses: 2,
aesKey: emptyKey,
}
@@ -47,10 +50,10 @@ func TestTimeFlush(t *testing.T) {
one := now.Add(oneSec)
singleUse := ActiveUser{
Admin: true,
Type: passvault.AESRecord,
Admin: true,
Type: passvault.AESRecord,
Expiry: one,
Uses: 10,
Uses: 10,
aesKey: emptyKey,
}
@@ -76,5 +79,3 @@ func TestTimeFlush(t *testing.T) {
t.Fatalf("Error in pruning expired key")
}
}
+6 -5
View File
@@ -1,4 +1,7 @@
// Package padding adds and removes padding for AES-CBC mode.
//
// Copyright (c) 2013 CloudFlare, Inc.
package padding
import "errors"
@@ -6,7 +9,7 @@ import "errors"
// RemovePadding removes padding from clear data.
func RemovePadding(bytesPadded []byte) ([]byte, error) {
// last byte is padding byte
paddingLen := int(bytesPadded[len(bytesPadded) - 1])
paddingLen := int(bytesPadded[len(bytesPadded)-1])
if paddingLen > 16 {
return nil, errors.New("Padding incorrect")
}
@@ -18,12 +21,10 @@ func RemovePadding(bytesPadded []byte) ([]byte, error) {
// PadClearFile adds padding to clear file.
func PadClearFile(fileBytes []byte) (paddedFile []byte) {
// pad with zeros, last byte is the size of padding
paddingLen := 16 - len(fileBytes) % 16
paddingLen := 16 - len(fileBytes)%16
padding := make([]byte, paddingLen)
padding[paddingLen - 1] = byte(paddingLen)
padding[paddingLen-1] = byte(paddingLen)
paddedFile = append(fileBytes, padding...)
return
}
+37 -34
View File
@@ -1,20 +1,24 @@
// Package passvault manages the vault containing user records on disk.
// Package passvault manages the vault containing user records on
// disk.
//
// Copyright (c) 2013 CloudFlare, Inc.
package passvault
import (
"code.google.com/p/go.crypto/scrypt"
"crypto/sha1"
"crypto/aes"
"crypto/rsa"
"crypto/rand"
"crypto/cipher"
mrand "math/rand"
"math/big"
"io/ioutil"
"encoding/json"
"bytes"
"code.google.com/p/go.crypto/scrypt"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"encoding/binary"
"encoding/json"
"errors"
"io/ioutil"
"math/big"
mrand "math/rand"
"redoctober/padding"
)
@@ -35,41 +39,41 @@ const (
DEFAULT_VERSION = 1
)
// Set of encrypted records from disk
var records diskRecords
// Path of current vault
var localPath string
// DiskPasswordRecord is the set of password records on disk.
type DiskPasswordRecord struct {
Type string
Salt []byte
Type string
Salt []byte
HashedPassword []byte
KeySalt []byte
AESKey []byte
RSAKey struct {
RSAExp []byte
RSAExpIV []byte
RSAPrimeP []byte
KeySalt []byte
AESKey []byte
RSAKey struct {
RSAExp []byte
RSAExpIV []byte
RSAPrimeP []byte
RSAPrimePIV []byte
RSAPrimeQ []byte
RSAPrimeQ []byte
RSAPrimeQIV []byte
RSAPublic rsa.PublicKey
RSAPublic rsa.PublicKey
}
Admin bool
}
type diskRecords struct {
Version int
VaultId int
HmacKey []byte
Version int
VaultId int
HmacKey []byte
Passwords map[string]DiskPasswordRecord
}
// Summary is a minmal account summary.
type Summary struct {
Admin bool
Type string
Type string
}
// Intialization.
@@ -272,22 +276,22 @@ func InitFromDisk(path string) {
}
}
if rec.Type == RSARecord {
if len(rec.RSAKey.RSAExp) == 0 || len(rec.RSAKey.RSAExp) % 16 != 0 {
if len(rec.RSAKey.RSAExp) == 0 || len(rec.RSAKey.RSAExp)%16 != 0 {
formatErr = true
}
if len(rec.RSAKey.RSAPrimeP) == 0 || len(rec.RSAKey.RSAPrimeP) % 16 != 0 {
if len(rec.RSAKey.RSAPrimeP) == 0 || len(rec.RSAKey.RSAPrimeP)%16 != 0 {
formatErr = true
}
if len(rec.RSAKey.RSAPrimeQ) == 0 || len(rec.RSAKey.RSAPrimeQ) % 16 != 0 {
if len(rec.RSAKey.RSAPrimeQ) == 0 || len(rec.RSAKey.RSAPrimeQ)%16 != 0 {
formatErr = true
}
if len(rec.RSAKey.RSAExpIV) != 16 {
if len(rec.RSAKey.RSAExpIV) != 16 {
formatErr = true
}
if len(rec.RSAKey.RSAPrimePIV) != 16 {
if len(rec.RSAKey.RSAPrimePIV) != 16 {
formatErr = true
}
if len(rec.RSAKey.RSAPrimeQIV) != 16 {
if len(rec.RSAKey.RSAPrimeQIV) != 16 {
formatErr = true
}
}
@@ -404,7 +408,7 @@ func ChangePassword(name string, password string, newPassword string) (err error
return
}
} else if passwordRec.Type == RSARecord {
// encrypt RSA key with password key
// encrypt RSA key with password key
err = encryptRSARecord(&passwordRec, &rsaKey, newPassKey)
if err != nil {
return
@@ -619,4 +623,3 @@ func (passwordRec DiskPasswordRecord) ValidatePassword(password string) (err err
}
return
}
+10 -9
View File
@@ -1,3 +1,7 @@
// passvault_test: tests for passvault.go
//
// Copyright (c) 2013 CloudFlare, Inc.
package passvault
import (
@@ -9,10 +13,10 @@ var dummy = make([]byte, 16)
func TestUsesFlush(t *testing.T) {
singleUse := ActiveUser{
Admin: true,
Admin: true,
Expiry: nextYear,
Uses: 1,
key: emptyKey,
Uses: 1,
key: emptyKey,
}
LiveKeys["first"] = singleUse
@@ -22,7 +26,6 @@ func TestUsesFlush(t *testing.T) {
t.Fatalf("Error in number of live keys")
}
EncryptKey(dummy, "first")
FlushCache()
@@ -36,10 +39,10 @@ func TestTimeFlush(t *testing.T) {
one := now.Add(oneSec)
singleUse := ActiveUser{
Admin: true,
Admin: true,
Expiry: one,
Uses: 10,
key: emptyKey,
Uses: 10,
key: emptyKey,
}
LiveKeys["first"] = singleUse
@@ -64,5 +67,3 @@ func TestTimeFlush(t *testing.T) {
t.Fatalf("Error in pruning expired key")
}
}
+50 -47
View File
@@ -1,65 +1,70 @@
// Package redoctober contains the server code for Red October.
//
// Copyright (c) 2013 CloudFlare, Inc.
package main
import (
"fmt"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"flag"
"os"
"fmt"
"io/ioutil"
"net"
"net/http"
"crypto/tls"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"os"
"redoctober/core"
)
// list of URLs to register
// List of URLs to register
const (
Create string = "/create"
Summary = "/summary"
Delegate = "/delegate"
Password = "/password"
Encrypt = "/encrypt"
Decrypt = "/decrypt"
Modify = "/modify"
Create string = "/create"
Summary = "/summary"
Delegate = "/delegate"
Password = "/password"
Encrypt = "/encrypt"
Decrypt = "/decrypt"
Modify = "/modify"
)
// the channel handling user request
// The channel handling user requests
var process = make(chan userRequest)
type userRequest struct {
rt string
in []byte
rt string
in []byte
resp chan []byte
}
func init() {
go func () {
go func() {
for {
foo := <-process
req := <-process
switch {
case foo.rt == Create:
foo.resp <- core.Create(foo.in)
case foo.rt == Summary:
foo.resp <- core.Summary(foo.in)
case foo.rt == Delegate:
foo.resp <- core.Delegate(foo.in)
case foo.rt == Password:
foo.resp <- core.Password(foo.in)
case foo.rt == Encrypt:
foo.resp <- core.Encrypt(foo.in)
case foo.rt == Decrypt:
foo.resp <- core.Decrypt(foo.in)
case foo.rt == Modify:
foo.resp <- core.Modify(foo.in)
default:
fmt.Printf("Unknown! %s\n", foo.rt)
foo.resp <- []byte("Unknown command")
case req.rt == Create:
req.resp <- core.Create(req.in)
case req.rt == Summary:
req.resp <- core.Summary(req.in)
case req.rt == Delegate:
req.resp <- core.Delegate(req.in)
case req.rt == Password:
req.resp <- core.Password(req.in)
case req.rt == Encrypt:
req.resp <- core.Encrypt(req.in)
case req.rt == Decrypt:
req.resp <- core.Decrypt(req.in)
case req.rt == Modify:
req.resp <- core.Modify(req.in)
default:
fmt.Printf("Unknown! %s\n", req.rt)
req.resp <- []byte("Unknown command")
}
}
} ()
}()
}
func queueRequest(requestType string, w http.ResponseWriter, r *http.Request, c *tls.ConnectionState) {
@@ -70,15 +75,14 @@ func queueRequest(requestType string, w http.ResponseWriter, r *http.Request, c
response := make(chan []byte, 1)
req := userRequest{rt: requestType, in: body, resp: response}
process <-req
process <- req
code := <-response
w.Write(code)
}
func NewServer(addr string, certPath string, keyPath string, caPath string) (*http.Server, *net.Listener, error) {
// set up server
mux := http.NewServeMux()
srv := http.Server{
Addr: addr,
@@ -91,11 +95,11 @@ func NewServer(addr string, certPath string, keyPath string, caPath string) (*ht
}
config := tls.Config{
Certificates: []tls.Certificate{cert},
Rand: rand.Reader,
ClientAuth: tls.RequestClientCert,
Certificates: []tls.Certificate{cert},
Rand: rand.Reader,
ClientAuth: tls.RequestClientCert,
PreferServerCipherSuites: true,
SessionTicketsDisabled: true,
SessionTicketsDisabled: true,
}
config.Rand = rand.Reader
@@ -129,7 +133,7 @@ func NewServer(addr string, certPath string, keyPath string, caPath string) (*ht
lstnr := tls.NewListener(conn, &config)
for _, action := range []string {Create, Summary, Delegate, Password, Encrypt, Decrypt, Modify} {
for _, action := range []string{Create, Summary, Delegate, Password, Encrypt, Decrypt, Modify} {
var requestType = action
mux.HandleFunc(requestType, func(w http.ResponseWriter, r *http.Request) {
queueRequest(requestType, w, r, r.TLS)
@@ -148,7 +152,7 @@ redoctober /tmp/diskrecord.json localhost:8080 cert.pem cert.key
`
func main () {
func main() {
flag.Usage = func() {
fmt.Fprint(os.Stderr, usage)
flag.PrintDefaults()
@@ -172,4 +176,3 @@ func main () {
s, l, _ := NewServer(*addr, *certPath, *keyPath, *caPath)
s.Serve(*l)
}