github.com/code-to-go/safepool.lib@v0.0.0-20221205180519-ee25e63c226e/security/identity.go.bk (about) 1 package security 2 3 import ( 4 "bytes" 5 "github.com/code-to-go/safepool.lib/core" 6 "github.com/code-to-go/safepool.lib/protocol" 7 8 "github.com/golang/protobuf/proto" 9 "github.com/google/tink/go/hybrid" 10 "github.com/google/tink/go/insecurecleartextkeyset" 11 "github.com/google/tink/go/keyset" 12 "github.com/google/tink/go/signature" 13 ) 14 15 type Identity struct { 16 PublicCrypt *keyset.Handle 17 PublicHash *keyset.Handle 18 PrivateCrypt *keyset.Handle 19 PrivateHash *keyset.Handle 20 Nick string 21 } 22 23 func marshalKeyset(kh *keyset.Handle) ([]byte, error) { 24 exportedPriv := &keyset.MemReaderWriter{} 25 err := insecurecleartextkeyset.Write(kh, exportedPriv) 26 if core.IsErr(err, "cannot export encryption key: %v") { 27 return nil, err 28 } 29 data, err := proto.Marshal(exportedPriv.Keyset) 30 if core.IsErr(err, "cannot marshal keyset: %v") { 31 return nil, err 32 } 33 return data, nil 34 } 35 36 func NewIdentity(nick string) (Identity, error) { 37 var identity Identity 38 39 identity.Nick = nick 40 kh, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) // Other key templates can also be used. 41 if core.IsErr(err, "cannot generated signature ECDSAP256 key: %v") { 42 return identity, err 43 } 44 45 identity.PrivateHash = kh 46 kh, err = kh.Public() 47 if core.IsErr(err, "cannot derive public key from signature ECDSAP256 key: %v") { 48 return identity, err 49 } 50 identity.PublicHash = kh 51 52 kh, err = keyset.NewHandle(hybrid.ECIESHKDFAES128CTRHMACSHA256KeyTemplate()) 53 if core.IsErr(err, "cannot generated hybrid ECIESHKDFAES128CTRHMACSHA256 key: %v") { 54 return identity, err 55 } 56 identity.PrivateCrypt = kh 57 58 if core.IsErr(err, "cannot derive public key from ECIESHKDFAES128CTRHMACSHA256 key: %v") { 59 return identity, err 60 } 61 identity.PublicCrypt = kh 62 63 return identity, nil 64 } 65 66 func MarshalIdentity(identity Identity, private bool) ([]byte, error) { 67 var hk *keyset.Handle 68 69 if private { 70 hk = identity.PrivateCrypt 71 } else { 72 hk = identity.PublicCrypt 73 } 74 75 crypt, err := marshalKeyset(hk) 76 if core.IsErr(err, "cannot export private encryption key: %v") { 77 return nil, err 78 } 79 80 if private { 81 hk = identity.PrivateHash 82 } else { 83 hk = identity.PublicHash 84 } 85 hash, err := marshalKeyset(identity.PrivateCrypt) 86 if core.IsErr(err, "cannot export private encryption key: %v") { 87 return nil, err 88 } 89 90 i := protocol.Identity{ 91 Version: 1.0, 92 Private: private, 93 Crypt: crypt, 94 Hash: hash, 95 Nick: identity.Nick, 96 } 97 98 data, err := proto.Marshal(&i) 99 if core.IsErr(err, "cannot marshal protocol.Identity: %v") { 100 return nil, err 101 } 102 103 return data, err 104 } 105 106 func UnmarshalIdentity(data []byte) (Identity, error) { 107 var identity Identity 108 var i protocol.Identity 109 var hk *keyset.Handle 110 err := proto.Unmarshal(data, &i) 111 if core.IsErr(err, "cannot unmarshal identity: %v") { 112 return identity, err 113 } 114 115 identity.Nick = i.Nick 116 hk, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(bytes.NewReader(i.Crypt))) 117 if core.IsErr(err, "cannot unmarshal crypt key: %v") { 118 return identity, err 119 } 120 if i.Private { 121 identity.PrivateCrypt = hk 122 hk, err = hk.Public() 123 if core.IsErr(err, "cannot derive public key: %v") { 124 return identity, err 125 } 126 identity.PublicCrypt = hk 127 } else { 128 identity.PublicCrypt = hk 129 } 130 131 hk, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(bytes.NewReader(i.Hash))) 132 if core.IsErr(err, "cannot unmarshal hash key: %v") { 133 return identity, err 134 } 135 if i.Private { 136 identity.PrivateHash = hk 137 hk, err = hk.Public() 138 if core.IsErr(err, "cannot derive public key: %v") { 139 return identity, err 140 } 141 identity.PublicHash = hk 142 } else { 143 identity.PublicHash = hk 144 } 145 146 return identity, err 147 }