@@ -427,9 +427,9 @@ var (
427427 // The following errors are used multiple times
428428 // in Key.validate. We declare them here to avoid
429429 // duplication. They are not considered public errors.
430- errCoordOverflow = fmt .Errorf ("%w: overflowing coordinate" , ErrInvalidKey )
431- errReqParamsMissing = fmt .Errorf ("%w: required parameters missing" , ErrInvalidKey )
432- errInvalidCurve = fmt .Errorf ("%w: curve not supported for the given key type" , ErrInvalidKey )
430+ errCoordSizeMismatch = fmt .Errorf ("%w: coordinate size mismatch " , ErrInvalidKey )
431+ errReqParamsMissing = fmt .Errorf ("%w: required parameters missing" , ErrInvalidKey )
432+ errInvalidCurve = fmt .Errorf ("%w: curve not supported for the given key type" , ErrInvalidKey )
433433)
434434
435435// Validate ensures that the parameters set inside the Key are internally
@@ -439,28 +439,49 @@ func (k Key) validate(op KeyOp) error {
439439 switch k .Type {
440440 case KeyTypeEC2 :
441441 crv , x , y , d := k .EC2 ()
442+ // Check required paraemeters exist
442443 switch op {
443444 case KeyOpVerify :
444- if len ( x ) == 0 || len ( y ) == 0 {
445+ if x == nil || y == nil {
445446 return ErrEC2NoPub
446447 }
447448 case KeyOpSign :
448- if len ( d ) == 0 {
449+ if d == nil {
449450 return ErrNotPrivKey
450451 }
451452 }
452- if crv == CurveReserved || (len ( x ) == 0 && len ( y ) == 0 && len ( d ) == 0 ) {
453+ if crv == CurveReserved || (x == nil && y == nil && d == nil ) {
453454 return errReqParamsMissing
454455 }
456+
457+ // Then, validate their length if exist and if the size is known
455458 if size := curveSize (crv ); size > 0 {
456459 if len (y ) == 0 && len (x ) == size + 1 {
460+ // NOTE: RFC 9053 Section 7.1.1 describes compressed points in COSE_Key
461+ // using a boolean y-coordinate value (false/true). However, this code
462+ // currently assumes SEC1-style compression, where 0x02 or 0x03 is prepended
463+ // to the x-coordinate.
464+ //
465+ // This behavior may change in the future, for example, we might compute the
466+ // y-coordinate during UnmarshalCBOR, and MarshalCBOR would avoid emitting
467+ // compressed points entirely.
468+ //
469+ // In that case, this conditional may become unnecessary, since the general
470+ // length check below (`len(x) > 0 && len(x) != size`) would already catch
471+ // invalid compressed input.
472+ //
473+ // See discussion in https://github.com/veraison/go-cose/pull/223 .
474+ // Consider revisiting this logic in a future update.
457475 return fmt .Errorf ("%w: compressed point not supported" , ErrInvalidPubKey )
458476 }
459- if len (x ) != size || len (y ) != size {
460- return ErrInvalidPubKey
477+ if len (x ) > 0 && len (x ) != size {
478+ return errCoordSizeMismatch
479+ }
480+ if len (y ) > 0 && len (y ) != size {
481+ return errCoordSizeMismatch
461482 }
462483 if len (d ) > 0 && len (d ) != size {
463- return ErrInvalidPrivKey
484+ return errCoordSizeMismatch
464485 }
465486 }
466487 switch crv {
@@ -472,21 +493,27 @@ func (k Key) validate(op KeyOp) error {
472493 }
473494 case KeyTypeOKP :
474495 crv , x , d := k .OKP ()
496+ // Check required paraemeters exist
475497 switch op {
476498 case KeyOpVerify :
477- if len ( x ) == 0 {
499+ if x == nil {
478500 return ErrOKPNoPub
479501 }
480502 case KeyOpSign :
481- if len ( d ) == 0 {
503+ if d == nil {
482504 return ErrNotPrivKey
483505 }
484506 }
485- if crv == CurveReserved || (len ( x ) == 0 && len ( d ) == 0 ) {
507+ if crv == CurveReserved || (x == nil && d == nil ) {
486508 return errReqParamsMissing
487509 }
488- if (len (x ) > 0 && len (x ) != ed25519 .PublicKeySize ) || (len (d ) > 0 && len (d ) != ed25519 .SeedSize ) {
489- return errCoordOverflow
510+
511+ // Then, validate their length if exist and if the size is known
512+ if len (x ) > 0 && len (x ) != ed25519 .PublicKeySize {
513+ return errCoordSizeMismatch
514+ }
515+ if len (d ) > 0 && len (d ) != ed25519 .SeedSize {
516+ return errCoordSizeMismatch
490517 }
491518 switch crv {
492519 case CurveP256 , CurveP384 , CurveP521 :
0 commit comments