Update keys

This commit is contained in:
mcrakhman 2022-07-13 20:52:56 +02:00 committed by Mikhail Iudin
parent 8265774754
commit 2ac69e480e
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
7 changed files with 338 additions and 257 deletions

View File

@ -21,7 +21,7 @@ type Keychain struct {
ReadKeys map[string]*SymKey ReadKeys map[string]*SymKey
ReadKeysByHash map[uint64]*SymKey ReadKeysByHash map[uint64]*SymKey
GeneratedIdentities map[string]string GeneratedIdentities map[string]string
coder *keys.Ed25519SigningPubKeyDecoder coder keys.SigningPubKeyDecoder
} }
func NewKeychain() *Keychain { func NewKeychain() *Keychain {

175
util/keys/ed25519.go Normal file
View File

@ -0,0 +1,175 @@
package keys
import (
"bytes"
"crypto/ed25519"
"crypto/rand"
"crypto/subtle"
"errors"
"fmt"
"io"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey"
)
// Ed25519PrivateKey is an ed25519 private key.
type Ed25519PrivateKey struct {
k ed25519.PrivateKey
}
// Ed25519PublicKey is an ed25519 public key.
type Ed25519PublicKey struct {
k ed25519.PublicKey
}
func NewSigningEd25519PubKeyFromBytes(bytes []byte) (SigningPubKey, error) {
return UnmarshalEd25519PublicKey(bytes)
}
func GenerateRandomEd25519KeyPair() (SigningPrivKey, SigningPubKey, error) {
return GenerateEd25519Key(rand.Reader)
}
// GenerateEd25519Key generates a new ed25519 private and public key pair.
func GenerateEd25519Key(src io.Reader) (SigningPrivKey, SigningPubKey, error) {
pub, priv, err := ed25519.GenerateKey(src)
if err != nil {
return nil, nil, err
}
return &Ed25519PrivateKey{
k: priv,
},
&Ed25519PublicKey{
k: pub,
},
nil
}
// Raw private key bytes.
func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
// The Ed25519 private key contains two 32-bytes curve points, the private
// key and the public key.
// It makes it more efficient to get the public key without re-computing an
// elliptic curve multiplication.
buf := make([]byte, len(k.k))
copy(buf, k.k)
return buf, nil
}
func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:]
}
// Equals compares two ed25519 private keys.
func (k *Ed25519PrivateKey) Equals(o Key) bool {
edk, ok := o.(*Ed25519PrivateKey)
if !ok {
return keyEquals(k, o)
}
return subtle.ConstantTimeCompare(k.k, edk.k) == 1
}
// GetPublic returns an ed25519 public key from a private key.
func (k *Ed25519PrivateKey) GetPublic() SigningPubKey {
return &Ed25519PublicKey{k: k.pubKeyBytes()}
}
// Sign returns a signature from an input message.
func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) {
return ed25519.Sign(k.k, msg), nil
}
// Raw public key bytes.
func (k *Ed25519PublicKey) Raw() ([]byte, error) {
return k.k, nil
}
// Equals compares two ed25519 public keys.
func (k *Ed25519PublicKey) Equals(o Key) bool {
edk, ok := o.(*Ed25519PublicKey)
if !ok {
return keyEquals(k, o)
}
return bytes.Equal(k.k, edk.k)
}
// Verify checks a signature agains the input data.
func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) {
return ed25519.Verify(k.k, data, sig), nil
}
// UnmarshalEd25519PublicKey returns a public key from input bytes.
func UnmarshalEd25519PublicKey(data []byte) (SigningPubKey, error) {
if len(data) != 32 {
return nil, errors.New("expect ed25519 public key data size to be 32")
}
return &Ed25519PublicKey{
k: ed25519.PublicKey(data),
}, nil
}
// UnmarshalEd25519PrivateKey returns a private key from input bytes.
func UnmarshalEd25519PrivateKey(data []byte) (SigningPrivKey, error) {
switch len(data) {
case ed25519.PrivateKeySize + ed25519.PublicKeySize:
// Remove the redundant public key. See issue #36.
redundantPk := data[ed25519.PrivateKeySize:]
pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize]
if subtle.ConstantTimeCompare(pk, redundantPk) == 0 {
return nil, errors.New("expected redundant ed25519 public key to be redundant")
}
// No point in storing the extra data.
newKey := make([]byte, ed25519.PrivateKeySize)
copy(newKey, data[:ed25519.PrivateKeySize])
data = newKey
case ed25519.PrivateKeySize:
default:
return nil, fmt.Errorf(
"expected ed25519 data size to be %d or %d, got %d",
ed25519.PrivateKeySize,
ed25519.PrivateKeySize+ed25519.PublicKeySize,
len(data),
)
}
return &Ed25519PrivateKey{
k: ed25519.PrivateKey(data),
}, nil
}
type Ed25519SigningPubKeyDecoder struct{}
func NewEd25519Decoder() SigningPubKeyDecoder {
return &Ed25519SigningPubKeyDecoder{}
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromBytes(bytes []byte) (SigningPubKey, error) {
return NewSigningEd25519PubKeyFromBytes(bytes)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromString(identity string) (SigningPubKey, error) {
pubKeyRaw, err := strkey.Decode(0x5b, identity)
if err != nil {
return nil, err
}
return e.DecodeFromBytes(pubKeyRaw)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromStringIntoBytes(identity string) ([]byte, error) {
return strkey.Decode(0x5b, identity)
}
func (e *Ed25519SigningPubKeyDecoder) EncodeToString(pubkey SigningPubKey) (string, error) {
raw, err := pubkey.Raw()
if err != nil {
return "", err
}
return strkey.Encode(0x5b, raw)
}

View File

@ -0,0 +1,14 @@
package keys
type EncryptionPrivKey interface {
Key
Decrypt([]byte) ([]byte, error)
GetPublic() EncryptionPubKey
}
type EncryptionPubKey interface {
Key
Encrypt(data []byte) ([]byte, error)
}

7
util/keys/key.go Normal file
View File

@ -0,0 +1,7 @@
package keys
type Key interface {
Equals(Key) bool
Raw() ([]byte, error)
}

View File

@ -1,256 +0,0 @@
package keys
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"crypto/subtle"
"crypto/x509"
"errors"
"io"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/strkey"
"github.com/libp2p/go-libp2p-core/crypto"
crypto_pb "github.com/libp2p/go-libp2p-core/crypto/pb"
)
type SigningPubKey crypto.PubKey
type SigningPrivKey crypto.PrivKey
var MinRsaKeyBits = 2048
var ErrKeyLengthTooSmall = errors.New("error key length too small")
type Key interface {
Equals(Key) bool
Raw() ([]byte, error)
}
type EncryptionPrivKey interface {
Key
Decrypt([]byte) ([]byte, error)
GetPublic() EncryptionPubKey
}
type EncryptionPubKey interface {
Key
Encrypt(data []byte) ([]byte, error)
}
type EncryptionRsaPrivKey struct {
privKey rsa.PrivateKey
}
type EncryptionRsaPubKey struct {
pubKey rsa.PublicKey
}
func (e *EncryptionRsaPubKey) Equals(key Key) bool {
other, ok := (key).(*EncryptionRsaPubKey)
if !ok {
return keyEquals(e, key)
}
return e.pubKey.N.Cmp(other.pubKey.N) == 0 && e.pubKey.E == other.pubKey.E
}
func (e *EncryptionRsaPubKey) Raw() ([]byte, error) {
return x509.MarshalPKIXPublicKey(&e.pubKey)
}
func (e *EncryptionRsaPubKey) Encrypt(data []byte) ([]byte, error) {
hash := sha512.New()
return rsa.EncryptOAEP(hash, rand.Reader, &e.pubKey, data, nil)
}
func (e *EncryptionRsaPrivKey) Equals(key Key) bool {
other, ok := (key).(*EncryptionRsaPrivKey)
if !ok {
return keyEquals(e, key)
}
return e.privKey.N.Cmp(other.privKey.N) == 0 && e.privKey.E == other.privKey.E
}
func (e *EncryptionRsaPrivKey) Raw() ([]byte, error) {
b := x509.MarshalPKCS1PrivateKey(&e.privKey)
return b, nil
}
func (e *EncryptionRsaPrivKey) Decrypt(bytes []byte) ([]byte, error) {
hash := sha512.New()
return rsa.DecryptOAEP(hash, rand.Reader, &e.privKey, bytes, nil)
}
func (e *EncryptionRsaPrivKey) GetPublic() EncryptionPubKey {
return &EncryptionRsaPubKey{pubKey: e.privKey.PublicKey}
}
func GenerateRandomRSAKeyPair(bits int) (EncryptionPrivKey, EncryptionPubKey, error) {
return GenerateRSAKeyPair(bits, rand.Reader)
}
func GenerateRSAKeyPair(bits int, src io.Reader) (EncryptionPrivKey, EncryptionPubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrKeyLengthTooSmall
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
}
pk := priv.PublicKey
return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil
}
func NewEncryptionRsaPrivKeyFromBytes(bytes []byte) (EncryptionPrivKey, error) {
sk, err := x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
return nil, err
}
if sk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPrivKey{privKey: *sk}, nil
}
func NewEncryptionRsaPubKeyFromBytes(bytes []byte) (EncryptionPubKey, error) {
pub, err := x509.ParsePKIXPublicKey(bytes)
if err != nil {
return nil, err
}
pk, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not actually an rsa public key")
}
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPubKey{pubKey: *pk}, nil
}
func NewSigningEd25519PubKeyFromBytes(bytes []byte) (SigningPubKey, error) {
return crypto.UnmarshalEd25519PublicKey(bytes)
}
func GenerateRandomEd25519KeyPair() (SigningPrivKey, SigningPubKey, error) {
return crypto.GenerateEd25519Key(rand.Reader)
}
func keyEquals(k1, k2 Key) bool {
a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
}
type Ed25519SigningPubKeyDecoder struct{}
func NewEd25519Decoder() *Ed25519SigningPubKeyDecoder {
return &Ed25519SigningPubKeyDecoder{}
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromBytes(bytes []byte) (SigningPubKey, error) {
return NewSigningEd25519PubKeyFromBytes(bytes)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromString(identity string) (SigningPubKey, error) {
pubKeyRaw, err := strkey.Decode(0x5b, identity)
if err != nil {
return nil, err
}
return e.DecodeFromBytes(pubKeyRaw)
}
func (e *Ed25519SigningPubKeyDecoder) DecodeFromStringIntoBytes(identity string) ([]byte, error) {
return strkey.Decode(0x5b, identity)
}
func (e *Ed25519SigningPubKeyDecoder) EncodeToString(pubkey crypto.PubKey) (string, error) {
raw, err := pubkey.Raw()
if err != nil {
return "", err
}
return strkey.Encode(0x5b, raw)
}
type SigningPubKeyDecoder interface {
DecodeFromBytes(bytes []byte) (SigningPubKey, error)
DecodeFromString(identity string) (SigningPubKey, error)
DecodeFromStringIntoBytes(identity string) ([]byte, error)
}
// Below keys are required for testing and mocking purposes
type EmptyRecorderEncryptionKey struct {
recordedEncrypted [][]byte
recordedDecrypted [][]byte
}
func (f *EmptyRecorderEncryptionKey) Equals(key Key) bool {
return true
}
func (f *EmptyRecorderEncryptionKey) Raw() ([]byte, error) {
panic("can't get bytes from this key")
}
func (f *EmptyRecorderEncryptionKey) GetPublic() EncryptionPubKey {
panic("this key doesn't have a public key")
}
func (f *EmptyRecorderEncryptionKey) Encrypt(msg []byte) ([]byte, error) {
f.recordedEncrypted = append(f.recordedEncrypted, msg)
return msg, nil
}
func (f *EmptyRecorderEncryptionKey) Decrypt(msg []byte) ([]byte, error) {
f.recordedDecrypted = append(f.recordedDecrypted, msg)
return msg, nil
}
type SignatureVerificationPayload struct {
message []byte
signature []byte
}
type EmptyRecorderVerificationKey struct {
verifications []SignatureVerificationPayload
}
func (e *EmptyRecorderVerificationKey) Bytes() ([]byte, error) {
panic("can't get bytes from this key")
}
func (e *EmptyRecorderVerificationKey) Equals(key crypto.Key) bool {
return true
}
func (e *EmptyRecorderVerificationKey) Raw() ([]byte, error) {
panic("can't get bytes from this key")
}
func (e *EmptyRecorderVerificationKey) Type() crypto_pb.KeyType {
panic("can't get type from this key")
}
func (e *EmptyRecorderVerificationKey) Verify(data []byte, sig []byte) (bool, error) {
e.verifications = append(e.verifications, SignatureVerificationPayload{
message: data,
signature: sig,
})
return true, nil
}
func NewMockSigningPubKeyFromBytes(bytes []byte) (SigningPubKey, error) {
return &EmptyRecorderVerificationKey{}, nil
}

119
util/keys/rsa.go Normal file
View File

@ -0,0 +1,119 @@
package keys
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"crypto/subtle"
"crypto/x509"
"errors"
"io"
)
var MinRsaKeyBits = 2048
var ErrKeyLengthTooSmall = errors.New("error key length too small")
type EncryptionRsaPrivKey struct {
privKey rsa.PrivateKey
}
type EncryptionRsaPubKey struct {
pubKey rsa.PublicKey
}
func (e *EncryptionRsaPubKey) Equals(key Key) bool {
other, ok := (key).(*EncryptionRsaPubKey)
if !ok {
return keyEquals(e, key)
}
return e.pubKey.N.Cmp(other.pubKey.N) == 0 && e.pubKey.E == other.pubKey.E
}
func (e *EncryptionRsaPubKey) Raw() ([]byte, error) {
return x509.MarshalPKIXPublicKey(&e.pubKey)
}
func (e *EncryptionRsaPubKey) Encrypt(data []byte) ([]byte, error) {
hash := sha512.New()
return rsa.EncryptOAEP(hash, rand.Reader, &e.pubKey, data, nil)
}
func (e *EncryptionRsaPrivKey) Equals(key Key) bool {
other, ok := (key).(*EncryptionRsaPrivKey)
if !ok {
return keyEquals(e, key)
}
return e.privKey.N.Cmp(other.privKey.N) == 0 && e.privKey.E == other.privKey.E
}
func (e *EncryptionRsaPrivKey) Raw() ([]byte, error) {
b := x509.MarshalPKCS1PrivateKey(&e.privKey)
return b, nil
}
func (e *EncryptionRsaPrivKey) Decrypt(bytes []byte) ([]byte, error) {
hash := sha512.New()
return rsa.DecryptOAEP(hash, rand.Reader, &e.privKey, bytes, nil)
}
func (e *EncryptionRsaPrivKey) GetPublic() EncryptionPubKey {
return &EncryptionRsaPubKey{pubKey: e.privKey.PublicKey}
}
func GenerateRandomRSAKeyPair(bits int) (EncryptionPrivKey, EncryptionPubKey, error) {
return GenerateRSAKeyPair(bits, rand.Reader)
}
func GenerateRSAKeyPair(bits int, src io.Reader) (EncryptionPrivKey, EncryptionPubKey, error) {
if bits < MinRsaKeyBits {
return nil, nil, ErrKeyLengthTooSmall
}
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
}
pk := priv.PublicKey
return &EncryptionRsaPrivKey{privKey: *priv}, &EncryptionRsaPubKey{pubKey: pk}, nil
}
func NewEncryptionRsaPrivKeyFromBytes(bytes []byte) (EncryptionPrivKey, error) {
sk, err := x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
return nil, err
}
if sk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPrivKey{privKey: *sk}, nil
}
func NewEncryptionRsaPubKeyFromBytes(bytes []byte) (EncryptionPubKey, error) {
pub, err := x509.ParsePKIXPublicKey(bytes)
if err != nil {
return nil, err
}
pk, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, errors.New("not actually an rsa public key")
}
if pk.N.BitLen() < MinRsaKeyBits {
return nil, ErrKeyLengthTooSmall
}
return &EncryptionRsaPubKey{pubKey: *pk}, nil
}
func keyEquals(k1, k2 Key) bool {
a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
}

22
util/keys/signingkey.go Normal file
View File

@ -0,0 +1,22 @@
package keys
type SigningPrivKey interface {
Key
Sign([]byte) ([]byte, error)
GetPublic() SigningPubKey
}
type SigningPubKey interface {
Key
Verify(data []byte, sig []byte) (bool, error)
}
type SigningPubKeyDecoder interface {
DecodeFromBytes(bytes []byte) (SigningPubKey, error)
DecodeFromString(identity string) (SigningPubKey, error)
DecodeFromStringIntoBytes(identity string) ([]byte, error)
EncodeToString(pubkey SigningPubKey) (string, error)
}