Skip to content

Commit

Permalink
Eliminate remaining usages of deprecated ecliptic package
Browse files Browse the repository at this point in the history
Signed-off-by: Steffen Vogel <[email protected]>
  • Loading branch information
stv0g committed Nov 28, 2023
1 parent fa6fb34 commit ef742e1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 30 deletions.
14 changes: 6 additions & 8 deletions key.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ package piv

import (
"crypto"
"crypto/ecdh"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rsa"
"encoding/asn1"
"errors"
Expand Down Expand Up @@ -36,8 +36,6 @@ var (
errUnsupportedTouchPolicy = errors.New("unsupported touch policy")
errUnsupportedKeyType = errors.New("unsupported key type")
errUnsupportedOrigin = errors.New("unsupported origin")
errPointsNotOnCurve = errors.New("resulting points are not on curve")
errPointsNotCompressed = errors.New("points were not uncompressed")
)

// UnsupportedCurveError is used when a key has an unsupported curve
Expand Down Expand Up @@ -139,18 +137,18 @@ func decodePublic(b []byte, alg Algorithm) (pub crypto.PublicKey, err error) {
}

case AlgECCP256:
if pub, err = decodeECPublic(tvs, elliptic.P256()); err != nil {
return nil, fmt.Errorf("failed to decode elliptic curve public key: %w", err)
if pub, err = decodeECDSAPublic(tvs, ecdh.P256()); err != nil {
return nil, fmt.Errorf("failed to decode P256 public key: %w", err)
}

case AlgECCP384:
if pub, err = decodeECPublic(tvs, elliptic.P384()); err != nil {
return nil, fmt.Errorf("failed to decode elliptic curve public key: %w", err)
if pub, err = decodeECDSAPublic(tvs, ecdh.P384()); err != nil {
return nil, fmt.Errorf("failed to decode P384 public key: %w", err)
}

case AlgEd25519:
if pub, err = decodeEd25519Public(tvs); err != nil {
return nil, fmt.Errorf("failed to decode ed25519 public key: %w", err)
return nil, fmt.Errorf("failed to decode Ed25519 public key: %w", err)
}

default:
Expand Down
61 changes: 39 additions & 22 deletions key_eccp.go → key_ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package piv

import (
"crypto"
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
"fmt"
Expand Down Expand Up @@ -56,7 +57,12 @@ func (k *ECPPPrivateKey) SharedKey(peer *ecdsa.PublicKey) ([]byte, error) {
if peer.Curve.Params().BitSize != k.pub.Curve.Params().BitSize {
return nil, errMismatchingAlgorithms
}
msg := elliptic.Marshal(peer.Curve, peer.X, peer.Y)

peerECDH, err := peer.ECDH()
if err != nil {
return nil, fmt.Errorf("failed to convert key: %w", err)
}

return k.auth.do(k.c, k.pp, func(tx *iso.Transaction) ([]byte, error) {
var alg Algorithm
size := k.pub.Params().BitSize
Expand All @@ -74,7 +80,7 @@ func (k *ECPPPrivateKey) SharedKey(peer *ecdsa.PublicKey) ([]byte, error) {
resp, err := sendTLV(k.c.tx, iso.InsGeneralAuthenticate, byte(alg), k.slot.Key,
tlv.New(0x7c,
tlv.New(0x82),
tlv.New(0x85, msg),
tlv.New(0x85, peerECDH.Bytes()),
),
)
if err != nil {
Expand All @@ -89,34 +95,19 @@ func (k *ECPPPrivateKey) SharedKey(peer *ecdsa.PublicKey) ([]byte, error) {
})
}

func decodeECPublic(tvs tlv.TagValues, curve elliptic.Curve) (*ecdsa.PublicKey, error) {
func decodeECDSAPublic(tvs tlv.TagValues, curve ecdh.Curve) (*ecdsa.PublicKey, error) {
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=95
p, _, ok := tvs.Get(0x86)
if !ok {
return nil, fmt.Errorf("%w: no points", errUnmarshal)
}

// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=96
size := curve.Params().BitSize / 8
if len(p) != (size*2)+1 {
return nil, fmt.Errorf("%w of points: %d", errUnexpectedLength, len(p))
}

// Are points uncompressed?
if p[0] != 0x04 {
return nil, errPointsNotCompressed
}
p = p[1:]

var x, y big.Int
x.SetBytes(p[:size])
y.SetBytes(p[size:])

if !curve.IsOnCurve(&x, &y) {
return nil, errPointsNotOnCurve
pk, err := curve.NewPublicKey(p)
if err != nil {
return nil, err
}

return &ecdsa.PublicKey{Curve: curve, X: &x, Y: &y}, nil
return ecdhToECDSAPublicKey(pk)
}

func signEC(tx *iso.Transaction, slot Slot, pub *ecdsa.PublicKey, data []byte) ([]byte, error) {
Expand Down Expand Up @@ -163,3 +154,29 @@ func algEC(pub *ecdsa.PublicKey) (Algorithm, error) {
return 0, UnsupportedCurveError{curve: size}
}
}

func ecdhToECDSAPublicKey(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, UnsupportedCurveError{}
}
}
File renamed without changes.
File renamed without changes.

0 comments on commit ef742e1

Please sign in to comment.