forked from SherClockHolmes/webpush-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlegacy.go
76 lines (69 loc) · 2.04 KB
/
legacy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package webpush
import (
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
"encoding/base64"
"fmt"
"math/big"
)
// ecdhPublicKeyToECDSA converts an ECDH key to an ECDSA key.
// This is deprecated as per https://github.com/golang/go/issues/63963
// but we need to do it in order to parse the legacy private key format.
func ecdhPublicKeyToECDSA(key *ecdh.PublicKey) (*ecdsa.PublicKey, error) {
rawKey := key.Bytes()
switch key.Curve() {
case ecdh.P256():
return &ecdsa.PublicKey{
Curve: elliptic.P256(),
X: big.NewInt(0).SetBytes(rawKey[1:33]),
Y: big.NewInt(0).SetBytes(rawKey[33:]),
}, nil
case ecdh.P384():
return &ecdsa.PublicKey{
Curve: elliptic.P384(),
X: big.NewInt(0).SetBytes(rawKey[1:49]),
Y: big.NewInt(0).SetBytes(rawKey[49:]),
}, nil
case ecdh.P521():
return &ecdsa.PublicKey{
Curve: elliptic.P521(),
X: big.NewInt(0).SetBytes(rawKey[1:67]),
Y: big.NewInt(0).SetBytes(rawKey[67:]),
}, nil
default:
return nil, fmt.Errorf("cannot convert non-NIST *ecdh.PublicKey to *ecdsa.PublicKey")
}
}
func ecdhPrivateKeyToECDSA(key *ecdh.PrivateKey) (*ecdsa.PrivateKey, error) {
// see https://github.com/golang/go/issues/63963
pubKey, err := ecdhPublicKeyToECDSA(key.PublicKey())
if err != nil {
return nil, fmt.Errorf("converting PublicKey part of *ecdh.PrivateKey: %w", err)
}
return &ecdsa.PrivateKey{
PublicKey: *pubKey,
D: big.NewInt(0).SetBytes(key.Bytes()),
}, nil
}
// DecodeLegacyVAPIDPrivateKey decodes the legacy string private key format
// returned by GenerateVAPIDKeys in v1.
func DecodeLegacyVAPIDPrivateKey(key string) (*VAPIDKeys, error) {
bytes, err := decodeSubscriptionKey(key)
if err != nil {
return nil, err
}
ecdhPrivKey, err := ecdh.P256().NewPrivateKey(bytes)
if err != nil {
return nil, err
}
ecdsaPrivKey, err := ecdhPrivateKeyToECDSA(ecdhPrivKey)
if err != nil {
return nil, err
}
publicKey := base64.RawURLEncoding.EncodeToString(ecdhPrivKey.PublicKey().Bytes())
return &VAPIDKeys{
privateKey: ecdsaPrivKey,
publicKey: publicKey,
}, nil
}