Skip to content

Commit

Permalink
chore: Address crypto/elliptic package deprecations (#32806)
Browse files Browse the repository at this point in the history
* chore: Address crypto/elliptic package deprecations

* Pre-allocate slices, drop needless `[:]`
  • Loading branch information
codingllama authored Oct 3, 2023
1 parent ce42cd9 commit 6483245
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
32 changes: 19 additions & 13 deletions lib/auth/mocku2f/mocku2f.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,20 @@ type signRegisterResult struct {
}

func (muk *Key) signRegister(appIDHash, clientDataHash []byte) (*signRegisterResult, error) {
//nolint:staticcheck // SA1019 requires Go 1.21 in go.mod and non-insignificant changes. TODO: fix.
pubKey := elliptic.Marshal(elliptic.P256(), muk.PrivateKey.PublicKey.X, muk.PrivateKey.PublicKey.Y)
// Marshal pubKey into the uncompressed "4||X||Y" form.
ecdhPubKey, err := muk.PrivateKey.PublicKey.ECDH()
if err != nil {
return nil, trace.Wrap(err)
}
pubKey := ecdhPubKey.Bytes()

var dataToSign []byte
dataToSign = append(dataToSign[:], 0)
dataToSign = append(dataToSign[:], appIDHash[:]...)
dataToSign = append(dataToSign[:], clientDataHash[:]...)
dataToSign = append(dataToSign[:], muk.KeyHandle[:]...)
dataToSign = append(dataToSign[:], pubKey[:]...)
cap := 1 + len(appIDHash) + len(clientDataHash) + len(muk.KeyHandle) + len(pubKey)
dataToSign := make([]byte, 0, cap)
dataToSign = append(dataToSign, 0)
dataToSign = append(dataToSign, appIDHash...)
dataToSign = append(dataToSign, clientDataHash...)
dataToSign = append(dataToSign, muk.KeyHandle...)
dataToSign = append(dataToSign, pubKey...)

dataHash := sha256.Sum256(dataToSign)

Expand All @@ -173,13 +178,14 @@ func (muk *Key) signRegister(appIDHash, clientDataHash []byte) (*signRegisterRes
flags = uint8(protocol.FlagUserPresent | protocol.FlagUserVerified | protocol.FlagAttestedCredentialData)
}

var regData []byte
cap = 1 + len(pubKey) + 1 + len(muk.KeyHandle) + len(muk.Cert) + len(sig)
regData := make([]byte, 0, cap)
regData = append(regData, flags)
regData = append(regData, pubKey[:]...)
regData = append(regData, pubKey...)
regData = append(regData, byte(len(muk.KeyHandle)))
regData = append(regData, muk.KeyHandle[:]...)
regData = append(regData, muk.Cert[:]...)
regData = append(regData, sig[:]...)
regData = append(regData, muk.KeyHandle...)
regData = append(regData, muk.Cert...)
regData = append(regData, sig...)

return &signRegisterResult{
RawResp: regData,
Expand Down
28 changes: 19 additions & 9 deletions lib/auth/webauthncli/u2f_register.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package webauthncli
import (
"bytes"
"context"
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
Expand All @@ -26,6 +27,7 @@ import (
"encoding/binary"
"encoding/json"
"fmt"
"math/big"

"github.com/flynn/u2f/u2ftoken"
"github.com/fxamacker/cbor/v2"
Expand Down Expand Up @@ -180,21 +182,29 @@ func parseU2FRegistrationResponse(resp []byte) (*u2fRegistrationResponse, error)
}
buf = buf[1:]

// public key
//nolint:staticcheck // SA1019 requires Go 1.21 in go.mod and non-insignificant changes. TODO: fix.
x, y := elliptic.Unmarshal(elliptic.P256(), buf[:pubKeyLen])
if x == nil {
return nil, trace.BadParameter("failed to parse public key")
// public key, "4||X||Y" form.
pubKeyBytes := buf[:pubKeyLen]
// Validate pubKey points.
if _, err := ecdh.P256().NewPublicKey(pubKeyBytes); err != nil {
return nil, trace.Wrap(err, "unmarshal public key")
}
buf = buf[pubKeyLen:]
// There's no API to pry away X and Y from ecdh.PublicKey, so we do it
// manually, but only after the key is validated.
const uncompressedForm = 4
if pubKeyBytes[0] != uncompressedForm {
return nil, trace.BadParameter("public key not in uncompressed form")
}
pubKeyBytes = pubKeyBytes[1:] // holds X||Y
l := len(pubKeyBytes) / 2 // holds the size of a coordinate (X or Y)
pubKey := &ecdsa.PublicKey{
Curve: elliptic.P256(),
X: x,
Y: y,
X: new(big.Int).SetBytes(pubKeyBytes[:l]),
Y: new(big.Int).SetBytes(pubKeyBytes[l:]),
}
buf = buf[pubKeyLen:]

// key handle
l := int(buf[0])
l = int(buf[0]) // holds the keyHandle length.
buf = buf[1:]
// Size checking resumed from now on.
if len(buf) < l {
Expand Down

0 comments on commit 6483245

Please sign in to comment.