github.com/hoffie/larasync@v0.0.0-20151025221940-0384d2bddcef/repository/keystore.go (about) 1 package repository 2 3 import ( 4 "crypto/rand" 5 "errors" 6 "fmt" 7 8 "github.com/hoffie/larasync/helpers/crypto" 9 edhelpers "github.com/hoffie/larasync/helpers/ed25519" 10 "github.com/hoffie/larasync/repository/content" 11 ) 12 13 const ( 14 // Key Sizes 15 16 // PrivateKeySize is the keySize which is used for signatures in the 17 // system. 18 PrivateKeySize = crypto.PrivateKeySize 19 // PublicKeySize is the keySize for public signature keys. 20 PublicKeySize = crypto.PublicKeySize 21 // EncryptionKeySize represents the size of the key used for 22 // encrypting. 23 EncryptionKeySize = crypto.EncryptionKeySize 24 // HashingKeySize represents the size of the key used for 25 // generating content hashes (HMAC). 26 HashingKeySize = crypto.HashingKeySize 27 28 // ids for our keys in the storage 29 encryptionKeyName = "encryption.key" 30 hashingKeyName = "hashing.key" 31 signingPrivateKeyName = "signing.priv" 32 signingPublicKeyName = "signing.pub" 33 ) 34 35 // KeyStore is responsible for loading keys from the storage backend. 36 type KeyStore struct { 37 base string 38 storage *content.ByteStorage 39 } 40 41 // NewKeyStore returns a new KeyStore instance. 42 func NewKeyStore(storage content.Storage) *KeyStore { 43 ks := &KeyStore{storage: content.NewByteStorage(storage)} 44 return ks 45 } 46 47 // SetEncryptionKey sets the encryption key 48 func (ks *KeyStore) SetEncryptionKey(key [EncryptionKeySize]byte) error { 49 return ks.storage.SetBytes(encryptionKeyName, key[:]) 50 } 51 52 // EncryptionKey returns the encryption key. 53 func (ks *KeyStore) EncryptionKey() ([EncryptionKeySize]byte, error) { 54 key, err := ks.storage.GetBytes(encryptionKeyName) 55 if len(key) != EncryptionKeySize { 56 return [EncryptionKeySize]byte{}, fmt.Errorf( 57 "invalid key length (%d)", len(key)) 58 } 59 var arrKey [EncryptionKeySize]byte 60 copy(arrKey[:], key) 61 return arrKey, err 62 } 63 64 // SetSigningPrivateKey sets the signing private key 65 func (ks *KeyStore) SetSigningPrivateKey(key [PrivateKeySize]byte) error { 66 return ks.storage.SetBytes(signingPrivateKeyName, key[:]) 67 } 68 69 // SigningPrivateKey returns the signing private key. 70 func (ks *KeyStore) SigningPrivateKey() ([PrivateKeySize]byte, error) { 71 key, err := ks.storage.GetBytes(signingPrivateKeyName) 72 if len(key) != PrivateKeySize { 73 return [PrivateKeySize]byte{}, fmt.Errorf( 74 "invalid key length (%d)", len(key)) 75 } 76 var arrKey [PrivateKeySize]byte 77 copy(arrKey[:], key) 78 return arrKey, err 79 } 80 81 // SetSigningPublicKey sets the signing key's public key. 82 func (ks *KeyStore) SetSigningPublicKey(key []byte) error { 83 return ks.storage.SetBytes(signingPublicKeyName, key) 84 } 85 86 // SigningPublicKey returns the signing public key. 87 func (ks *KeyStore) SigningPublicKey() ([PublicKeySize]byte, error) { 88 privKey, err := ks.SigningPrivateKey() 89 if err != nil { 90 return ks.signingPublicKeyFromStorage() 91 } 92 return edhelpers.GetPublicKeyFromPrivate(privKey), nil 93 } 94 95 // signingPubkeyFromStorage returns the repository signing public key. 96 // 97 // It tries to retrieve the stored copy and is only called if the public key 98 // cannot be derived from the private key (i.e. if the private key is not 99 // available in this repository). 100 func (ks *KeyStore) signingPublicKeyFromStorage() ([PublicKeySize]byte, error) { 101 key, err := ks.storage.GetBytes(signingPublicKeyName) 102 if len(key) != PublicKeySize { 103 return [PublicKeySize]byte{}, fmt.Errorf( 104 "invalid key length (%d)", len(key)) 105 } 106 var arrKey [PublicKeySize]byte 107 copy(arrKey[:], key) 108 return arrKey, err 109 } 110 111 // SetHashingKey sets the repository hashing key (content addressing) 112 func (ks *KeyStore) SetHashingKey(key [HashingKeySize]byte) error { 113 return ks.storage.SetBytes(hashingKeyName, key[:]) 114 } 115 116 // HashingKey returns the repository signing private key. 117 func (ks *KeyStore) HashingKey() ([HashingKeySize]byte, error) { 118 key, err := ks.storage.GetBytes(hashingKeyName) 119 if len(key) != HashingKeySize { 120 return [HashingKeySize]byte{}, fmt.Errorf( 121 "invalid key length (%d)", len(key)) 122 } 123 var arrKey [HashingKeySize]byte 124 copy(arrKey[:], key) 125 return arrKey, err 126 } 127 128 // CreateEncryptionKey generates a random encryption key. 129 func (ks *KeyStore) CreateEncryptionKey() error { 130 key := make([]byte, EncryptionKeySize) 131 _, err := rand.Read(key) 132 if err != nil { 133 return err 134 } 135 err = ks.storage.SetBytes(encryptionKeyName, key) 136 return err 137 } 138 139 // CreateSigningKey generates a random signing key. 140 func (ks *KeyStore) CreateSigningKey() error { 141 _, privKey, err := edhelpers.GenerateKey() 142 if err != nil { 143 return err 144 } 145 if privKey == nil { 146 return errors.New("no private key generated") 147 } 148 err = ks.SetSigningPrivateKey(*privKey) 149 return err 150 } 151 152 // CreateHashingKey generates a random hashing key. 153 func (ks *KeyStore) CreateHashingKey() error { 154 key := make([]byte, HashingKeySize) 155 var arrKey [HashingKeySize]byte 156 _, err := rand.Read(key) 157 if err != nil { 158 return err 159 } 160 copy(arrKey[:], key) 161 err = ks.SetHashingKey(arrKey) 162 return err 163 }