// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package subtle import ( "errors" "fmt" "math/big" ) var errUnsupportedEncoding = errors.New("ecdsa: unsupported encoding") // ECDSASignature is a struct holding the r and s values of an ECDSA signature. type ECDSASignature struct { R, S *big.Int } // NewECDSASignature creates a new ECDSASignature instance. func NewECDSASignature(r, s *big.Int) *ECDSASignature { return &ECDSASignature{R: r, S: s} } // EncodeECDSASignature converts the signature to the given encoding format. func (sig *ECDSASignature) EncodeECDSASignature(encoding, curveName string) ([]byte, error) { var enc []byte var err error switch encoding { case "IEEE_P1363": enc, err = ieeeP1363Encode(sig, curveName) case "DER": enc, err = asn1encode(sig) default: err = errUnsupportedEncoding } if err != nil { return nil, fmt.Errorf("ecdsa: can't convert ECDSA signature to %s encoding: %v", encoding, err) } return enc, nil } // DecodeECDSASignature creates a new ECDSA signature using the given byte slice. // The function assumes that the byte slice is the concatenation of the BigEndian // representation of two big integer r and s. func DecodeECDSASignature(encodedBytes []byte, encoding string) (*ECDSASignature, error) { var sig *ECDSASignature var err error switch encoding { case "IEEE_P1363": sig, err = ieeeP1363Decode(encodedBytes) case "DER": sig, err = asn1decode(encodedBytes) default: err = errUnsupportedEncoding } if err != nil { return nil, fmt.Errorf("ecdsa: %s", err) } return sig, nil } // ValidateECDSAParams validates ECDSA parameters. // The hash's strength must not be weaker than the curve's strength. // DER and IEEE_P1363 encodings are supported. func ValidateECDSAParams(hashAlg string, curve string, encoding string) error { switch encoding { case "DER": case "IEEE_P1363": default: return errUnsupportedEncoding } switch curve { case "NIST_P256": if hashAlg != "SHA256" { return errors.New("invalid hash type, expect SHA-256") } case "NIST_P384": if hashAlg != "SHA384" && hashAlg != "SHA512" { return errors.New("invalid hash type, expect SHA-384 or SHA-512") } case "NIST_P521": if hashAlg != "SHA512" { return errors.New("invalid hash type, expect SHA-512") } default: return fmt.Errorf("unsupported curve: %s", curve) } return nil }