Example #1
0
// Opens a file to read the configuration elements from.
// fn: Filename to open.
// password: Password to encrypt and decrypt secure content.
// Has to be either, 16, 24, or 32 in length.
func Open(fn, password string) (*Configurator, error) {
	pl := len(password)
	switch pl {
	default:
		return nil, aes.KeySizeError(pl)
	case 16, 24, 32:
		break
	}
	f, err := os.Open(fn)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	scanner := bufio.NewScanner(f)
	lines := make(map[string]string)

	for i := 1; scanner.Scan(); i++ {
		str := strings.Split(scanner.Text(), "=")
		lines[str[0]] = str[1]
	}

	block, err := aes.NewCipher([]byte(password))
	if err != nil {
		return nil, err
	}

	return &Configurator{
		filename:    fn,
		lines:       lines,
		cipherBlock: block,
		decrypted:   make(map[string]string),
	}, nil
}
Example #2
0
// Read checks the validity of a file and attempts to decrypt it.
func (m *MutableFile) Read(p []byte) (n int, err error) {
	// delegate VK checking to Verify()
	if m.Cap.rk == nil {
		return 0, CapabilityError
	}

	ok, err := m.Verify()
	if err != nil {
		return 0, err
	}

	if !ok {
		return 0, rsa.ErrVerification
	}

	// TODO don't repeat this file read
	filePath := path.Join(m.storageDir, m.filename)
	rawFile, err := ioutil.ReadFile(filePath)
	if err != nil {
		return 0, err
	}

	sigSize := AsymmetricKeySize / 8
	sigOffset := len(rawFile) - sigSize

	// for generating EK from RK
	fileSalt := rawFile[:SaltSize]
	ek := truncHash(TagEKFromSaltRK, append(m.Cap.rk, fileSalt...), SymmetricKeySize)
	if ek == nil || len(ek) != SymmetricKeySize {
		return 0, aes.KeySizeError(len(ek))
	}

	block, err := aes.NewCipher(ek)
	if err != nil {
		return 0, err
	}
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return 0, err
	}

	// skip salt, get nonce, stop before ciphertext
	nonce := rawFile[SaltSize : SaltSize+gcm.NonceSize()]

	// skip salt and nonce, get ciphertext|tag, stop before sig
	ciphertext := rawFile[SaltSize+gcm.NonceSize() : sigOffset]

	decryptBytes, err := gcm.Open(nil, nonce, ciphertext, nil)
	if err != nil {
		return 0, nil
	}

	if cap(p) < len(decryptBytes) {
		return copy(p, decryptBytes[:cap(p)]), io.ErrShortBuffer
	} else {
		return copy(p, decryptBytes), io.EOF
	}
}
Example #3
0
// Write writes a file. Format is
// {
//   fileSalt [16]byte
//   gcmNonce [12]byte
//   ciphertext [len(contents)]byte
//   gcmTag [16]byte
//   signature [256]byte
// }
func (m *MutableFile) Write(data []byte) (n int, err error) {

	// TODO check capability derivation chains
	if m.Cap.sk == nil || m.Cap.rk == nil || m.salt == nil {
		return 0, CapabilityError
	}

	ek := truncHash(TagEKFromSaltRK, append(m.Cap.rk, m.salt...), SymmetricKeySize)
	if ek == nil || len(ek) != SymmetricKeySize {
		return 0, aes.KeySizeError(len(ek))
	}

	block, err := aes.NewCipher(ek)
	if err != nil {
		return 0, err
	}
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return 0, err
	}

	buf := make([]byte, len(m.salt))
	copy(buf, m.salt)

	nonce := make([]byte, gcm.NonceSize())
	n, err = rand.Read(nonce)
	if n != gcm.NonceSize() || err != nil {
		panic("rand.Read failed!1!!")
	}
	buf = append(buf, nonce...)

	buf = gcm.Seal(buf, nonce, data, nil)

	// remember that this is hashing all of salt|nonce|ciphertext|tag
	hashed := sha256.Sum256(buf)
	sig, err := rsa.SignPKCS1v15(rand.Reader, m.Cap.sk, crypto.SHA256, hashed[:])
	if err != nil {
		return 0, err
	}

	out, err := os.Create(path.Join(m.storageDir, m.filename))
	if err != nil {
		return 0, err
	}
	defer out.Close()
	bufN, err := out.Write(buf)
	if err != nil {
		return 0, err
	}
	sigN, err := out.Write(sig)
	if err != nil {
		return 0, err
	}

	return bufN + sigN, nil
}
Example #4
0
func TestCreateEndpoint(t *testing.T) {
	useMockFuncs()
	defer useStdFuncs()

	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	mckEndHandler := NewMockHandler(mockCtrl)

	Convey("Should allocate update endpoints", t, func() {
		app := NewApplication()
		app.endpointTemplate = testEndpointTemplate

		Convey("Should not encrypt endpoints without a key", func() {
			app.SetTokenKey("")
			app.SetEndpointHandler(mckEndHandler)

			mckEndHandler.EXPECT().URL().Return("https://example.com")

			endpoint, err := app.CreateEndpoint("123")
			So(err, ShouldBeNil)
			So(endpoint, ShouldEqual, "https://example.com/123")
		})

		Convey("Should encrypt endpoints with a key", func() {
			app.SetTokenKey("HVozKz_n-DPopP5W877DpRKQOW_dylVf")
			app.SetEndpointHandler(mckEndHandler)

			mckEndHandler.EXPECT().URL().Return("https://example.com")

			endpoint, err := app.CreateEndpoint("456")
			So(err, ShouldBeNil)
			So(endpoint, ShouldEqual,
				"https://example.com/AAAAAAAAAAAAAAAAAAAAAGMKig==")
		})

		Convey("Should reject invalid keys", func() {
			app.SetTokenKey("lLyhlLk8qus1ky4ER8yjN5o=")
			app.SetEndpointHandler(mckEndHandler)

			_, err := app.CreateEndpoint("123")
			So(err, ShouldEqual, aes.KeySizeError(17))
		})

		Convey("Should return a relative URL without an update handler", func() {
			app.SetTokenKey("O03rpLsdafhIhJEjEJt-CgVHyqHI650oy0pZZvplKDc=")
			endpoint, err := app.CreateEndpoint("789")
			So(err, ShouldBeNil)
			So(endpoint, ShouldEqual, "/AAAAAAAAAAAAAAAAAAAAAPfdsA==")
		})
	})
}
Example #5
0
func Test_Decode(t *testing.T) {
	var (
		decrypted, expected []byte
		err                 error
	)
	key := []byte{0xf8, 0x59, 0x4, 0x72, 0x1c, 0xa, 0xc, 0x85, 0x5b, 0x7a,
		0x61, 0x26, 0xa5, 0x5a, 0xe2, 0x3b}
	encrypted := "6MgxfnBKjWtSNm6Q9WunFbj2hcjmeDudKuWUAeU="

	if decrypted, err = Decode(key, encrypted); err != nil {
		t.Errorf("Error decoding value: %s", err)
	}
	expected = []byte("Hello, world!")
	if !bytes.Equal(decrypted, expected) {
		t.Errorf("Unexpected result decoding with key: want %#v; got %#v",
			expected, decrypted)
	}
	if _, err = Decode(key[:14], "6MgxfnBKjWtSNm6Q9WunFbj2hcjmeDudKuWUAeU="); err != aes.KeySizeError(14) {
		t.Errorf("Invalid key size: want aes.KeySizeError(14); got %s", err)
	}
	if _, err = Decode(key, "!@#$%^&*()-+[]{}"); err != base64.CorruptInputError(0) {
		t.Errorf("Invalid Base64: want base64.CorruptInputError(0); got %s", err)
	}
	if _, err = Decode(key, encrypted[:8]); err != ValueSizeError(6) {
		t.Errorf("Encrypted value too short: want ValueSizeError(6); got %s", err)
	}
	if decrypted, err = Decode(nil, encrypted); err != nil {
		t.Errorf("Error decoding without key: %s", err)
	}
	expected = []byte(encrypted)
	if !bytes.Equal(decrypted, expected) {
		t.Errorf("Unexpected result decoding without key: want %#v; got %#v",
			expected, decrypted)
	}
	if decrypted, err = Decode(key, ""); err != nil {
		t.Errorf("Error decoding empty string: %s", err)
	}
	if len(decrypted) != 0 {
		t.Errorf("Unexpected result decoding empty string: got %#v", decrypted)
	}
	// Empty payload with valid IV.
	if decrypted, err = Decode(key, "dEmnrPZHgiOgttx5lhkx4w=="); err != nil {
		t.Errorf("Error decoding empty payload: %s", err)
	}
	if len(decrypted) != 0 {
		t.Errorf("Unexpected result decoding empty payload: got %#v", decrypted)
	}
}
Example #6
0
// Decrypt decrypts data using 256-bit AES-GCM.  This both hides the content of
// the data and provides a check that it hasn't been altered.  Expects input
// form nonce|ciphertext|tag where '|' indicates concatenation.
func Decrypt(ciphertext, key []byte) (plaintext []byte, err error) {
	if len(key) != aesKeySize {
		return nil, aes.KeySizeError(len(key))
	}

	aes, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(aes)
	if err != nil {
		return nil, err
	}

	return gcm.Open(nil, ciphertext[:gcm.NonceSize()],
		ciphertext[gcm.NonceSize():], nil)
}
Example #7
0
// Encrypt encrypts data using 256-bit AES-GCM.  This both hides the content of
// the data and provides a check that it hasn't been altered.  Output takes the
// form nonce|ciphertext|tag where '|' indicates concatenation.
func Encrypt(plaintext, key []byte) (ciphertext []byte, err error) {
	if len(key) != aesKeySize {
		return nil, aes.KeySizeError(len(key))
	}

	aes, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(aes)
	if err != nil {
		return nil, err
	}

	nonce, err := generateBytes(gcm.NonceSize())
	if err != nil {
		return nil, err
	}

	return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
Example #8
0
// NewAes256Gcm creates new Aes256Gcm with key
func NewAes256Gcm(key []byte) (*Aes256Gcm, error) {
	if len(key) != KeySize {
		return nil, aes.KeySizeError(len(key))
	}
	return &Aes256Gcm{key: key}, nil
}