// jwsHasher indicates suitable JWS algorithm name and a hash function // to use for signing a digest with the provided key. // It returns ("", 0) if the key is not supported. func jwsHasher(key crypto.Signer) (string, crypto.Hash) { switch key := key.(type) { case *rsa.PrivateKey: return "RS256", crypto.SHA256 case *ecdsa.PrivateKey: switch key.Params().Name { case "P-256": return "ES256", crypto.SHA256 case "P-384": return "ES384", crypto.SHA384 case "P-512": return "ES512", crypto.SHA512 } } return "", 0 }
// jwsSign signs the digest using the given key. // It returns ErrUnsupportedKey if the key type is unknown. // The hash is used only for RSA keys. func jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) { switch key := key.(type) { case *rsa.PrivateKey: return key.Sign(rand.Reader, digest, hash) case *ecdsa.PrivateKey: r, s, err := ecdsa.Sign(rand.Reader, key, digest) if err != nil { return nil, err } rb, sb := r.Bytes(), s.Bytes() size := key.Params().BitSize / 8 if size%8 > 0 { size++ } sig := make([]byte, size*2) copy(sig[size-len(rb):], rb) copy(sig[size*2-len(sb):], sb) return sig, nil } return nil, ErrUnsupportedKey }