Skip to content

Commit

Permalink
Merge pull request #1 from elixir-oslo/header
Browse files Browse the repository at this point in the history
Add GetHeader() method
  • Loading branch information
Dmytro Titov authored Jun 5, 2020
2 parents 389e2a2 + 9975075 commit ed442d0
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 109 deletions.
55 changes: 25 additions & 30 deletions keys/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var ed25519Algorithm = []int{1, 3, 101, 112}
var x25519Algorithm = []int{1, 3, 101, 110}

// GenerateKeyPair method generates X25519 key pair.
func GenerateKeyPair() (publicKey [chacha20poly1305.KeySize]byte, privateKey [chacha20poly1305.KeySize]byte, err error) {
func GenerateKeyPair() (publicKey, privateKey [chacha20poly1305.KeySize]byte, err error) {
edPublicKey, edPrivateKey, err := ed25519.GenerateKey(nil)
if err != nil {
return
Expand Down Expand Up @@ -119,16 +119,15 @@ func ReadPrivateKey(reader io.Reader, passPhrase []byte) (privateKey [chacha20po
return privateKey, errors.New("private key format not supported")
}

func readCrypt4GHPrivateKey(pemBytes []byte, passPhrase []byte) (privateKey [chacha20poly1305.KeySize]byte, err error) {
buf := bytes.Buffer{}
buf.Write(pemBytes[len(magic):])
func readCrypt4GHPrivateKey(pemBytes, passPhrase []byte) (privateKey [chacha20poly1305.KeySize]byte, err error) {
buffer := bytes.NewBuffer(pemBytes[len(magic):])
var length uint16
err = binary.Read(&buf, binary.BigEndian, &length)
err = binary.Read(buffer, binary.BigEndian, &length)
if err != nil {
return
}
kdfName := make([]byte, length)
err = binary.Read(&buf, binary.BigEndian, &kdfName)
err = binary.Read(buffer, binary.BigEndian, &kdfName)
if err != nil {
return
}
Expand All @@ -142,35 +141,35 @@ func readCrypt4GHPrivateKey(pemBytes []byte, passPhrase []byte) (privateKey [cha
if passPhrase == nil {
return privateKey, errors.New("private key is password-protected, need a password for decryption")
}
err = binary.Read(&buf, binary.BigEndian, &length)
err = binary.Read(buffer, binary.BigEndian, &length)
if err != nil {
return
}
err = binary.Read(&buf, binary.BigEndian, &rounds)
err = binary.Read(buffer, binary.BigEndian, &rounds)
if err != nil {
return
}
salt = make([]byte, length-4)
err = binary.Read(&buf, binary.BigEndian, &salt)
err = binary.Read(buffer, binary.BigEndian, &salt)
if err != nil {
return
}
}
err = binary.Read(&buf, binary.BigEndian, &length)
err = binary.Read(buffer, binary.BigEndian, &length)
if err != nil {
return
}
ciphername := make([]byte, length)
err = binary.Read(&buf, binary.BigEndian, &ciphername)
err = binary.Read(buffer, binary.BigEndian, &ciphername)
if err != nil {
return
}
err = binary.Read(&buf, binary.BigEndian, &length)
err = binary.Read(buffer, binary.BigEndian, &length)
if err != nil {
return
}
payload := make([]byte, length)
err = binary.Read(&buf, binary.BigEndian, &payload)
err = binary.Read(buffer, binary.BigEndian, &payload)
if err != nil {
return
}
Expand Down Expand Up @@ -315,55 +314,51 @@ func WriteCrypt4GHX25519PrivateKey(writer io.Writer, privateKey [chacha20poly130
}
encryptedPrivateKey := aead.Seal(nil, nonce[:], privateKey[:], nil)

buf := bytes.Buffer{}
_, err = buf.Write([]byte(magic))
if err != nil {
return err
}
buffer := bytes.NewBuffer([]byte(magic))
length := uint16(len(kdfName))
err = binary.Write(&buf, binary.BigEndian, length)
err = binary.Write(buffer, binary.BigEndian, length)
if err != nil {
return err
}
err = binary.Write(&buf, binary.BigEndian, []byte(kdfName))
err = binary.Write(buffer, binary.BigEndian, []byte(kdfName))
if err != nil {
return err
}
rounds := [4]byte{}
roundsWithSalt := append(rounds[:], salt[:]...)
length = uint16(len(roundsWithSalt))
err = binary.Write(&buf, binary.BigEndian, length)
err = binary.Write(buffer, binary.BigEndian, length)
if err != nil {
return err
}
err = binary.Write(&buf, binary.BigEndian, roundsWithSalt)
err = binary.Write(buffer, binary.BigEndian, roundsWithSalt)
if err != nil {
return err
}
length = uint16(len(supportedCipherName))
err = binary.Write(&buf, binary.BigEndian, length)
err = binary.Write(buffer, binary.BigEndian, length)
if err != nil {
return err
}
err = binary.Write(&buf, binary.BigEndian, []byte(supportedCipherName))
err = binary.Write(buffer, binary.BigEndian, []byte(supportedCipherName))
if err != nil {
return err
}
nonceWithKey := append(nonce[:], encryptedPrivateKey...)
length = uint16(len(nonceWithKey))
err = binary.Write(&buf, binary.BigEndian, length)
err = binary.Write(buffer, binary.BigEndian, length)
if err != nil {
return err
}
err = binary.Write(&buf, binary.BigEndian, nonceWithKey)
err = binary.Write(buffer, binary.BigEndian, nonceWithKey)
if err != nil {
return err
}

block := pem.Block{
Type: crypt4GHPrivateKeyHeader,
Headers: nil,
Bytes: buf.Bytes(),
Bytes: buffer.Bytes(),
}
return pem.Encode(writer, &block)
}
Expand All @@ -385,7 +380,7 @@ func DerivePublicKey(privateKey [chacha20poly1305.KeySize]byte) (publicKey [chac
}

// GenerateReaderSharedKey generates shared key for recipient, based on ECDH and BLAKE2 SHA-512.
func GenerateReaderSharedKey(privateKey [chacha20poly1305.KeySize]byte, publicKey [chacha20poly1305.KeySize]byte) (*[]byte, error) {
func GenerateReaderSharedKey(privateKey, publicKey [chacha20poly1305.KeySize]byte) (*[]byte, error) {
derivedPublicKey := DerivePublicKey(privateKey)
diffieHellmanKey, err := curve25519.X25519(privateKey[:], publicKey[:])
if err != nil {
Expand All @@ -395,7 +390,7 @@ func GenerateReaderSharedKey(privateKey [chacha20poly1305.KeySize]byte, publicKe
}

// GenerateWriterSharedKey generates shared key for sender, based on ECDH and BLAKE2 SHA-512.
func GenerateWriterSharedKey(privateKey [chacha20poly1305.KeySize]byte, publicKey [chacha20poly1305.KeySize]byte) (*[]byte, error) {
func GenerateWriterSharedKey(privateKey, publicKey [chacha20poly1305.KeySize]byte) (*[]byte, error) {
derivedPublicKey := DerivePublicKey(privateKey)
diffieHellmanKey, err := curve25519.X25519(privateKey[:], publicKey[:])
if err != nil {
Expand All @@ -404,7 +399,7 @@ func GenerateWriterSharedKey(privateKey [chacha20poly1305.KeySize]byte, publicKe
return generateSharedKey(diffieHellmanKey, publicKey, derivedPublicKey)
}

func generateSharedKey(diffieHellmanKey []byte, readerPublicKey [chacha20poly1305.KeySize]byte, writerPublicKey [chacha20poly1305.KeySize]byte) (*[]byte, error) {
func generateSharedKey(diffieHellmanKey []byte, readerPublicKey, writerPublicKey [chacha20poly1305.KeySize]byte) (*[]byte, error) {
combination := append(diffieHellmanKey, readerPublicKey[:]...)
combination = append(combination, writerPublicKey[:]...)
hash := blake2b.Sum512(combination)
Expand Down
24 changes: 12 additions & 12 deletions keys/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ func TestWriteOpenSSLX25519PrivateKey(t *testing.T) {
if err != nil {
t.Error(err)
}
buf := bytes.Buffer{}
err = WriteOpenSSLX25519PrivateKey(&buf, privateKey)
buffer := bytes.Buffer{}
err = WriteOpenSSLX25519PrivateKey(&buffer, privateKey)
if err != nil {
t.Error(err)
}
Expand All @@ -152,7 +152,7 @@ func TestWriteOpenSSLX25519PrivateKey(t *testing.T) {
if err != nil {
t.Error(err)
}
if !bytes.Equal(keyFileBytes, buf.Bytes()) {
if !bytes.Equal(keyFileBytes, buffer.Bytes()) {
t.Fail()
}
}
Expand All @@ -166,8 +166,8 @@ func TestWriteOpenSSLX25519PublicKey(t *testing.T) {
if err != nil {
t.Error(err)
}
buf := bytes.Buffer{}
err = WriteOpenSSLX25519PublicKey(&buf, publicKey)
buffer := bytes.Buffer{}
err = WriteOpenSSLX25519PublicKey(&buffer, publicKey)
if err != nil {
t.Error(err)
}
Expand All @@ -179,7 +179,7 @@ func TestWriteOpenSSLX25519PublicKey(t *testing.T) {
if err != nil {
t.Error(err)
}
if !bytes.Equal(keyFileBytes, buf.Bytes()) {
if !bytes.Equal(keyFileBytes, buffer.Bytes()) {
t.Fail()
}
}
Expand All @@ -193,12 +193,12 @@ func TestWriteCrypt4GHX25519PrivateKey(t *testing.T) {
if err != nil {
t.Error(err)
}
buf := bytes.Buffer{}
err = WriteCrypt4GHX25519PrivateKey(&buf, privateKey, []byte("password"))
buffer := bytes.Buffer{}
err = WriteCrypt4GHX25519PrivateKey(&buffer, privateKey, []byte("password"))
if err != nil {
t.Error(err)
}
privateKeyReconstructed, err := ReadPrivateKey(&buf, []byte("password"))
privateKeyReconstructed, err := ReadPrivateKey(&buffer, []byte("password"))
if err != nil {
t.Error(err)
}
Expand All @@ -216,8 +216,8 @@ func TestWriteCrypt4GHX25519PublicKey(t *testing.T) {
if err != nil {
t.Error(err)
}
buf := bytes.Buffer{}
err = WriteCrypt4GHX25519PublicKey(&buf, publicKey)
buffer := bytes.Buffer{}
err = WriteCrypt4GHX25519PublicKey(&buffer, publicKey)
if err != nil {
t.Error(err)
}
Expand All @@ -229,7 +229,7 @@ func TestWriteCrypt4GHX25519PublicKey(t *testing.T) {
if err != nil {
t.Error(err)
}
if !bytes.Equal(keyFileBytes, buf.Bytes()) {
if !bytes.Equal(keyFileBytes, buffer.Bytes()) {
t.Fail()
}
}
Expand Down
25 changes: 11 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func readPrivateKey(fileName string) (privateKey [chacha20poly1305.KeySize]byte,
return
}

func writeKeyPair(name string, publicKey [chacha20poly1305.KeySize]byte, privateKey [chacha20poly1305.KeySize]byte, format string, password string) error {
func writeKeyPair(name string, publicKey, privateKey [chacha20poly1305.KeySize]byte, format, password string) error {
publicKeyFileName := name + ".pub.pem"
privateKeyFileName := name + ".sec.pem"
if fileExists(publicKeyFileName) || fileExists(privateKeyFileName) {
Expand Down Expand Up @@ -251,10 +251,7 @@ func writeKeyPair(name string, publicKey [chacha20poly1305.KeySize]byte, private
return err
}
}
if err = privateKeyFile.Close(); err != nil {
return err
}
return nil
return privateKeyFile.Close()
}

func promptYesNo(message string) {
Expand Down Expand Up @@ -287,21 +284,21 @@ func fileExists(fileName string) bool {
func generateHelpMessage() string {
header := "crypt4gh [generate | encrypt | decrypt] <args>\n"

buf := bytes.Buffer{}
generateOptionsParser.WriteHelp(&buf)
generateUsage := buf.String()
buffer := bytes.Buffer{}
generateOptionsParser.WriteHelp(&buffer)
generateUsage := buffer.String()
generateUsage = strings.Replace(generateUsage, usageString, "", 1)
generateUsage = strings.Replace(generateUsage, applicationOptions, " "+generate, 1)

buf.Reset()
encryptOptionsParser.WriteHelp(&buf)
encryptUsage := buf.String()
buffer.Reset()
encryptOptionsParser.WriteHelp(&buffer)
encryptUsage := buffer.String()
encryptUsage = strings.Replace(encryptUsage, usageString, "", 1)
encryptUsage = strings.Replace(encryptUsage, applicationOptions, " "+encrypt, 1)

buf.Reset()
decryptOptionsParser.WriteHelp(&buf)
decryptUsage := buf.String()
buffer.Reset()
decryptOptionsParser.WriteHelp(&buffer)
decryptUsage := buffer.String()
decryptUsage = strings.Replace(decryptUsage, usageString, "", 1)
decryptUsage = strings.Replace(decryptUsage, applicationOptions, " "+decrypt, 1)

Expand Down
16 changes: 6 additions & 10 deletions model/headers/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ type Header struct {

// ReadHeader method strips off the header from the io.Reader and returns it as a byte array.
func ReadHeader(reader io.Reader) (header []byte, err error) {
buf := bytes.Buffer{}
var magicNumber = [8]byte{}
_, err = reader.Read(magicNumber[:])
if err != nil {
Expand All @@ -71,10 +70,7 @@ func ReadHeader(reader io.Reader) (header []byte, err error) {
if string(magicNumber[:]) != MagicNumber {
return header, errors.New("not a Crypt4GH file")
}
_, err = buf.Write(magicNumber[:])
if err != nil {
return
}
buffer := bytes.NewBuffer(magicNumber[:])
var version uint32
err = binary.Read(reader, binary.LittleEndian, &version)
if err != nil {
Expand All @@ -83,7 +79,7 @@ func ReadHeader(reader io.Reader) (header []byte, err error) {
if version != Version {
return header, fmt.Errorf("version %v not supported", version)
}
err = binary.Write(&buf, binary.LittleEndian, version)
err = binary.Write(buffer, binary.LittleEndian, version)
if err != nil {
return
}
Expand All @@ -92,7 +88,7 @@ func ReadHeader(reader io.Reader) (header []byte, err error) {
if err != nil {
return
}
err = binary.Write(&buf, binary.LittleEndian, headerPacketCount)
err = binary.Write(buffer, binary.LittleEndian, headerPacketCount)
if err != nil {
return
}
Expand All @@ -102,16 +98,16 @@ func ReadHeader(reader io.Reader) (header []byte, err error) {
if err != nil {
return
}
err = binary.Write(&buf, binary.LittleEndian, packetLength)
err = binary.Write(buffer, binary.LittleEndian, packetLength)
if err != nil {
return
}
_, err = io.CopyN(&buf, reader, int64(packetLength))
_, err = io.CopyN(buffer, reader, int64(packetLength-4)) // packetLength includes length of "packetLength"
if err != nil {
return
}
}
return buf.Bytes(), nil
return buffer.Bytes(), nil
}

// NewHeader method constructs Header from io.Reader and supplied private key.
Expand Down
Loading

0 comments on commit ed442d0

Please sign in to comment.