| index 59af685..50c316b 100644 |
| --- a/vapid_test.go |
| +++ b/vapid_test.go |
| @@ -3,8 +3,10 @@ package aviso |
| import ( |
| "crypto/ecdh" |
| "crypto/rand" |
| + "crypto/sha256" |
| "encoding/base64" |
| "errors" |
| + "math/big" |
| "strings" |
| "testing" |
| ) |
| @@ -41,12 +43,27 @@ func TestParsePrivateKeyRefusesBadInput(t *testing.T) { |
| if _, _, err := parsePrivateKey(""); !errors.Is(err, ErrEmptyPrivateKey) { |
| t.Fatalf("empty: got %v, want ErrEmptyPrivateKey", err) |
| } |
| - zero := base64.RawURLEncoding.EncodeToString(make([]byte, 32)) |
| + enc := base64.RawURLEncoding.EncodeToString |
| + zero := enc(make([]byte, 32)) |
| + // The P-256 group order n, and n-1 (the largest valid scalar). |
| + n, _ := new(big.Int).SetString("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16) |
| + nMinus1 := new(big.Int).Sub(n, big.NewInt(1)) |
| + nPlus1 := new(big.Int).Add(n, big.NewInt(1)) |
| + one := make([]byte, 32) |
| + one[31] = 1 |
| + good := enc(one) |
| + if _, _, err := parsePrivateKey(enc(nMinus1.FillBytes(make([]byte, 32)))); err != nil { |
| + t.Errorf("n-1 refused: %v", err) |
| + } |
| for name, in := range map[string]string{ |
| - "not base64": "!!!", |
| - "short": base64.RawURLEncoding.EncodeToString([]byte("short")), |
| - "zero scalar": zero, |
| - "padded": zero + "=", |
| + "not base64": "!!!", |
| + "short": enc([]byte("short")), |
| + "zero scalar": zero, |
| + "order n": enc(n.FillBytes(make([]byte, 32))), |
| + "above n": enc(nPlus1.FillBytes(make([]byte, 32))), |
| + "padded": good + "=", |
| + "newline": good[:10] + "\n" + good[10:], |
| + "trailing bits": good[:len(good)-1] + "F", // canonical ending is "E" |
| } { |
| if _, _, err := parsePrivateKey(in); !errors.Is(err, ErrInvalidPrivateKey) { |
| t.Errorf("%s: got %v, want ErrInvalidPrivateKey", name, err) |
| @@ -54,6 +71,19 @@ func TestParsePrivateKeyRefusesBadInput(t *testing.T) { |
| } |
| } |
| |
| +func TestKeyIDIsSHA256OfThePublicPoint(t *testing.T) { |
| + priv, _ := GenerateKey() |
| + pub, id, err := parsePrivateKey(priv) |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + point, _ := base64.RawURLEncoding.DecodeString(pub) |
| + sum := sha256.Sum256(point) |
| + if want := base64.RawURLEncoding.EncodeToString(sum[:]); id != want { |
| + t.Fatalf("key id = %s, want %s", id, want) |
| + } |
| +} |
| + |
| func TestParsePrivateKeyAgreesWithECDH(t *testing.T) { |
| k, err := ecdh.P256().GenerateKey(rand.Reader) |
| if err != nil { |