1// Copyright 2018 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17package signature_test 18 19import ( 20 "bytes" 21 "crypto/ed25519" 22 "encoding/hex" 23 "fmt" 24 "testing" 25 26 "github.com/google/go-cmp/cmp" 27 "google.golang.org/protobuf/proto" 28 "github.com/google/tink/go/core/registry" 29 "github.com/google/tink/go/internal/internalregistry" 30 "github.com/google/tink/go/signature/subtle" 31 "github.com/google/tink/go/subtle/random" 32 "github.com/google/tink/go/testutil" 33 ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto" 34 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 35) 36 37func TestED25519SignerGetPrimitiveBasic(t *testing.T) { 38 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 39 if err != nil { 40 t.Errorf("cannot obtain ED25519Signer key manager: %s", err) 41 } 42 pvtKey := testutil.NewED25519PrivateKey() 43 serializedKey, _ := proto.Marshal(pvtKey) 44 tmp, err := km.Primitive(serializedKey) 45 if err != nil { 46 t.Errorf("unexpect error in test case: %s ", err) 47 } 48 var s = tmp.(*subtle.ED25519Signer) 49 50 kmPub, err := registry.GetKeyManager(testutil.ED25519VerifierTypeURL) 51 if err != nil { 52 t.Errorf("cannot obtain ED25519Signer key manager: %s", err) 53 } 54 pubKey := pvtKey.PublicKey 55 serializedKey, _ = proto.Marshal(pubKey) 56 tmp, err = kmPub.Primitive(serializedKey) 57 if err != nil { 58 t.Errorf("unexpect error in test case: %s ", err) 59 } 60 var v = tmp.(*subtle.ED25519Verifier) 61 62 data := random.GetRandomBytes(1281) 63 signature, err := s.Sign(data) 64 if err != nil { 65 t.Errorf("unexpected error when signing: %s", err) 66 } 67 68 if err := v.Verify(signature, data); err != nil { 69 t.Errorf("unexpected error when verifying signature: %s", err) 70 } 71 72} 73 74func TestED25519SignGetPrimitiveWithInvalidInput(t *testing.T) { 75 // invalid params 76 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 77 if err != nil { 78 t.Errorf("cannot obtain ED25519Signer key manager: %s", err) 79 } 80 81 // invalid version 82 key := testutil.NewED25519PrivateKey() 83 key.Version = testutil.ED25519SignerKeyVersion + 1 84 serializedKey, _ := proto.Marshal(key) 85 if _, err := km.Primitive(serializedKey); err == nil { 86 t.Errorf("expect an error when version is invalid") 87 } 88 // nil input 89 if _, err := km.Primitive(nil); err == nil { 90 t.Errorf("expect an error when input is nil") 91 } 92 if _, err := km.Primitive([]byte{}); err == nil { 93 t.Errorf("expect an error when input is empty slice") 94 } 95} 96 97func TestED25519SignNewKeyBasic(t *testing.T) { 98 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 99 if err != nil { 100 t.Errorf("cannot obtain ED25519Signer key manager: %s", err) 101 } 102 serializedFormat, _ := proto.Marshal(testutil.NewED25519PrivateKey()) 103 tmp, err := km.NewKey(serializedFormat) 104 if err != nil { 105 t.Errorf("unexpected error: %s", err) 106 } 107 key := tmp.(*ed25519pb.Ed25519PrivateKey) 108 if err := validateED25519PrivateKey(key); err != nil { 109 t.Errorf("invalid private key in test case: %s", err) 110 } 111} 112 113func TestED25519PublicKeyDataBasic(t *testing.T) { 114 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 115 if err != nil { 116 t.Errorf("cannot obtain ED25519Signer key manager: %s", err) 117 } 118 pkm, ok := km.(registry.PrivateKeyManager) 119 if !ok { 120 t.Errorf("cannot obtain private key manager") 121 } 122 123 key := testutil.NewED25519PrivateKey() 124 serializedKey, _ := proto.Marshal(key) 125 126 pubKeyData, err := pkm.PublicKeyData(serializedKey) 127 if err != nil { 128 t.Errorf("unexpect error in test case: %s ", err) 129 } 130 if pubKeyData.TypeUrl != testutil.ED25519VerifierTypeURL { 131 t.Errorf("incorrect type url: %s", pubKeyData.TypeUrl) 132 } 133 if pubKeyData.KeyMaterialType != tinkpb.KeyData_ASYMMETRIC_PUBLIC { 134 t.Errorf("incorrect key material type: %d", pubKeyData.KeyMaterialType) 135 } 136 pubKey := new(ed25519pb.Ed25519PublicKey) 137 if err = proto.Unmarshal(pubKeyData.Value, pubKey); err != nil { 138 t.Errorf("invalid public key: %s", err) 139 } 140} 141 142func TestED25519PublicKeyDataWithInvalidInput(t *testing.T) { 143 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 144 if err != nil { 145 t.Errorf("cannot obtain ED25519Signer key manager: %s", err) 146 } 147 pkm, ok := km.(registry.PrivateKeyManager) 148 if !ok { 149 t.Errorf("cannot obtain private key manager") 150 } 151 // modified key 152 key := testutil.NewED25519PrivateKey() 153 serializedKey, _ := proto.Marshal(key) 154 serializedKey[0] = 0 155 if _, err := pkm.PublicKeyData(serializedKey); err == nil { 156 t.Errorf("expect an error when input is a modified serialized key") 157 } 158 // invalid with a single byte 159 if _, err := pkm.PublicKeyData([]byte{42}); err == nil { 160 t.Errorf("expect an error when input is an empty slice") 161 } 162} 163 164func TestED25519KeyMaterialType(t *testing.T) { 165 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 166 if err != nil { 167 t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err) 168 } 169 keyManager, ok := km.(internalregistry.DerivableKeyManager) 170 if !ok { 171 t.Fatalf("key manager is not DerivableKeyManager") 172 } 173 if got, want := keyManager.KeyMaterialType(), tinkpb.KeyData_ASYMMETRIC_PRIVATE; got != want { 174 t.Errorf("KeyMaterialType() = %v, want %v", got, want) 175 } 176} 177 178func TestED25519DeriveKey(t *testing.T) { 179 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 180 if err != nil { 181 t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err) 182 } 183 keyManager, ok := km.(internalregistry.DerivableKeyManager) 184 if !ok { 185 t.Fatalf("key manager is not DerivableKeyManager") 186 } 187 keyFormat, err := proto.Marshal(&ed25519pb.Ed25519KeyFormat{Version: testutil.ED25519SignerKeyVersion}) 188 if err != nil { 189 t.Fatalf("proto.Marshal() err = %v, want nil", err) 190 } 191 for _, test := range []struct { 192 name string 193 keyFormat []byte 194 }{ 195 { 196 // nil unmarshals to an empty proto, which implies version = 0. 197 name: "nil", 198 keyFormat: nil, 199 }, 200 { 201 // An empty proto implies version = 0. 202 name: "empty", 203 keyFormat: []byte{}, 204 }, 205 { 206 name: "specified", 207 keyFormat: keyFormat, 208 }, 209 } { 210 t.Run(test.name, func(t *testing.T) { 211 rand := random.GetRandomBytes(ed25519.SeedSize) 212 buf := &bytes.Buffer{} 213 buf.Write(rand) // never returns a non-nil error 214 k, err := keyManager.DeriveKey(test.keyFormat, buf) 215 if err != nil { 216 t.Fatalf("keyManager.DeriveKey() err = %v, want nil", err) 217 } 218 key := k.(*ed25519pb.Ed25519PrivateKey) 219 if got, want := len(key.KeyValue), ed25519.SeedSize; got != want { 220 t.Errorf("private key length = %d, want %d", got, want) 221 } 222 if diff := cmp.Diff(key.KeyValue, rand[:ed25519.SeedSize]); diff != "" { 223 t.Errorf("incorrect derived private key: diff = %v", diff) 224 } 225 if got, want := len(key.PublicKey.KeyValue), ed25519.PublicKeySize; got != want { 226 t.Errorf("public key length = %d, want %d", got, want) 227 } 228 if diff := cmp.Diff(key.PublicKey.KeyValue, []byte(ed25519.NewKeyFromSeed(rand))[32:]); diff != "" { 229 t.Errorf("incorrect derived public key: diff = %v", diff) 230 } 231 }) 232 } 233} 234 235func TestED25519DeriveKeyFailsWithInvalidKeyFormats(t *testing.T) { 236 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 237 if err != nil { 238 t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err) 239 } 240 keyManager, ok := km.(internalregistry.DerivableKeyManager) 241 if !ok { 242 t.Fatalf("key manager is not DerivableKeyManager") 243 } 244 invalidVersion, err := proto.Marshal(&ed25519pb.Ed25519KeyFormat{Version: 10}) 245 if err != nil { 246 t.Fatalf("proto.Marshal() err = %v, want nil", err) 247 } 248 // Proto messages start with a VarInt, which always ends with a byte with the 249 // MSB unset, so 0x80 is invalid. 250 invalidSerialization, err := hex.DecodeString("80") 251 if err != nil { 252 t.Errorf("hex.DecodeString() err = %v, want nil", err) 253 } 254 for _, test := range []struct { 255 name string 256 keyFormat []byte 257 }{ 258 { 259 name: "invalid version", 260 keyFormat: invalidVersion, 261 }, 262 { 263 name: "invalid serialization", 264 keyFormat: invalidSerialization, 265 }, 266 } { 267 t.Run(test.name, func(t *testing.T) { 268 buf := bytes.NewBuffer(random.GetRandomBytes(ed25519.SeedSize)) 269 if _, err := keyManager.DeriveKey(test.keyFormat, buf); err == nil { 270 t.Errorf("keyManager.DeriveKey() err = nil, want non-nil") 271 } 272 }) 273 } 274} 275 276func TestED25519DeriveKeyFailsWithInsufficientRandomness(t *testing.T) { 277 km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL) 278 if err != nil { 279 t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err) 280 } 281 keyManager, ok := km.(internalregistry.DerivableKeyManager) 282 if !ok { 283 t.Fatalf("key manager is not DerivableKeyManager") 284 } 285 keyFormat, err := proto.Marshal(&ed25519pb.Ed25519KeyFormat{Version: 0}) 286 if err != nil { 287 t.Fatalf("proto.Marshal() err = %v, want nil", err) 288 } 289 { 290 buf := bytes.NewBuffer(random.GetRandomBytes(ed25519.SeedSize)) 291 if _, err := keyManager.DeriveKey(keyFormat, buf); err != nil { 292 t.Errorf("keyManager.DeriveKey() err = %v, want nil", err) 293 } 294 } 295 { 296 insufficientBuf := bytes.NewBuffer(random.GetRandomBytes(ed25519.SeedSize - 1)) 297 if _, err := keyManager.DeriveKey(keyFormat, insufficientBuf); err == nil { 298 t.Errorf("keyManager.DeriveKey() err = nil, want non-nil") 299 } 300 } 301} 302 303func validateED25519PrivateKey(key *ed25519pb.Ed25519PrivateKey) error { 304 if key.Version != testutil.ED25519SignerKeyVersion { 305 return fmt.Errorf("incorrect private key's version: expect %d, got %d", 306 testutil.ED25519SignerKeyVersion, key.Version) 307 } 308 publicKey := key.PublicKey 309 if publicKey.Version != testutil.ED25519SignerKeyVersion { 310 return fmt.Errorf("incorrect public key's version: expect %d, got %d", 311 testutil.ED25519SignerKeyVersion, key.Version) 312 } 313 314 signer, err := subtle.NewED25519Signer(key.KeyValue) 315 if err != nil { 316 return fmt.Errorf("unexpected error when creating ED25519Sign: %s", err) 317 } 318 319 verifier, err := subtle.NewED25519Verifier(publicKey.KeyValue) 320 if err != nil { 321 return fmt.Errorf("unexpected error when creating ED25519Verify: %s", err) 322 } 323 for i := 0; i < 100; i++ { 324 data := random.GetRandomBytes(1281) 325 signature, err := signer.Sign(data) 326 if err != nil { 327 return fmt.Errorf("unexpected error when signing: %s", err) 328 } 329 330 if err := verifier.Verify(signature, data); err != nil { 331 return fmt.Errorf("unexpected error when verifying signature: %s", err) 332 } 333 } 334 return nil 335} 336