config.go 3.48 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
package user

import (
	"dfss/auth"
	"dfss/dfssc/common"
	"dfss/dfssc/security"
	"encoding/json"
	"fmt"
)

// Config represents the config file to be marshalled in json
type Config struct {
	KeyFile  string `json:"key"`
	KeyData  []byte `json:"keyData"`
	CertFile string `json:"cert"`
	CertData []byte `json:"certData"`
}

// NewConfig creates a new config object from the key and certificate provided
// The validity of those is checked later
func NewConfig(keyFile, certFile string) (*Config, error) {
	if !common.FileExists(keyFile) {
		return nil, fmt.Errorf("No such file: %s", keyFile)
	}

	if !common.FileExists(certFile) {
		return nil, fmt.Errorf("No such file: %s", certFile)
	}

	key, err := common.ReadFile(keyFile)

	if err != nil {
		return nil, err
	}

	cert, err := common.ReadFile(certFile)

	if err != nil {
		return nil, err
	}

	return &Config{
		KeyData:  key,
		KeyFile:  keyFile,
		CertData: cert,
		CertFile: certFile,
	}, nil

}

// SaveConfigToFile marshals checks the  validity of the certificate and private key,
// marshals the struct in JSON, encrypt the string using AES-256 with the provided passphrase,
// and finally save it to a file
func (c *Config) SaveConfigToFile(fileName, passphrase, keyPassphrase string) error {
	if common.FileExists(fileName) {
		return fmt.Errorf("Cannot overwrite file: %s", fileName)
	}

	if len(passphrase) < 4 {
		return fmt.Errorf("Passphrase should be at least 4 characters long")
	}

	err := c.checkData(keyPassphrase)
	if err != nil {
		return err
	}

	data, err := json.Marshal(c)
	if err != nil {
		return err
	}

	encodedData, err := security.EncryptStringAES(passphrase, data)
	if err != nil {
		return err
	}

	err = common.SaveToDisk(encodedData, fileName)
	return err
}

// DecodeConfiguration : decrypt and unmarshal the given configuration file
// to create a Config object. It also checks the validity of the certificate and private key
func DecodeConfiguration(fileName, keyPassphrase, confPassphrase string) (*Config, error) {
	if !common.FileExists(fileName) {
		return nil, fmt.Errorf("No such file: %s", fileName)
	}

	if len(confPassphrase) < 4 {
		return nil, fmt.Errorf("Passphrase should be at least 4 characters long")
	}

	encodedData, err := common.ReadFile(fileName)
	if err != nil {
		return nil, err
	}

	decodedData, err := security.DecryptAES(confPassphrase, encodedData)
	if err != nil {
		return nil, err
	}

	var config Config
	err = json.Unmarshal(decodedData, &config)
	if err != nil {
		return nil, err
	}

	err = config.checkData(keyPassphrase)
	if err != nil {
		return nil, err
	}

	return &config, nil
}

// Check that the certificate is valid, and that the private key is valid too
// using the passphrase
func (c *Config) checkData(keyPassphrase string) error {
	_, err := auth.PEMToCertificate(c.CertData)
	if err != nil {
		return err
	}

	_, err = auth.EncryptedPEMToPrivateKey(c.KeyData, keyPassphrase)
126
	return err
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
}

// SaveUserInformations save the certificate and private key to the files specified in the Config struct
func (c *Config) SaveUserInformations() error {
	if common.FileExists(c.KeyFile) {
		return fmt.Errorf("Cannot overwrite file: %s", c.KeyFile)
	}

	if common.FileExists(c.CertFile) {
		return fmt.Errorf("Cannot overwrite file: %s", c.CertFile)
	}

	err := common.SaveToDisk(c.KeyData, c.KeyFile)
	if err != nil {
		common.DeleteQuietly(c.KeyFile)
		return err
	}

	err = common.SaveToDisk(c.CertData, c.CertFile)
	if err != nil {
		common.DeleteQuietly(c.KeyFile)
		common.DeleteQuietly(c.CertFile)
		return err
	}

	return nil
}