Documentation ¶
Overview ¶
Package cose implements CBOR Object Signing and Encryption (COSE) defined in RFC8152.
Index ¶
- Constants
- Variables
- func RegisterEncryptAlgorithm(alg EncryptAlgorithm, ad bool, keyBits uint16, f func([]byte) (Crypter, error))
- func RegisterMacAlgorithm(alg MacAlgorithm, keyBits uint16, f func([]byte) (hash.Hash, error))
- func RegisterSignatureAlgorithm(alg SignatureAlgorithm, f func() crypto.Hash)
- type Crypter
- type Encrypt0
- type Encrypt0Tag
- type EncryptAlgorithm
- type Header
- type HeaderMap
- type HeaderParser
- type IntOrStr
- type Key
- func (k Key) Alg() (IntOrStr, bool)
- func (k Key) BaseIV() ([]byte, bool)
- func (k Key) IsEllipticCurveKey() bool
- func (k Key) IsOctetKeyPair() bool
- func (k Key) IsSymmetricKey() bool
- func (k Key) KeyOps() []IntOrStr
- func (k Key) Kid() ([]byte, bool)
- func (k Key) Kty() (IntOrStr, bool)
- func (k Key) MarshalCBOR() ([]byte, error)
- func (k Key) Public() (crypto.PublicKey, error)
- func (k *Key) UnmarshalCBOR(data []byte) error
- type KeyLabel
- type KeyType
- type Label
- type Mac0
- type Mac0Tag
- type MacAlgorithm
- type RFC8152Signer
- type Sign1
- type Sign1Tag
- type SignatureAlgorithm
Constants ¶
const ( SignTagNum uint64 = 98 Sign1TagNum uint64 = 18 EncryptTagNum uint64 = 96 Encrypt0TagNum uint64 = 16 MacTagNum uint64 = 97 Mac0TagNum uint64 = 17 )
COSE Tags
+-------+---------------+---------------+---------------------------+ | CBOR | cose-type | Data Item | Semantics | | Tag | | | | +-------+---------------+---------------+---------------------------+ | 98 | cose-sign | COSE_Sign | COSE Signed Data Object | | 18 | cose-sign1 | COSE_Sign1 | COSE Single Signer Data | | | | | Object | | 96 | cose-encrypt | COSE_Encrypt | COSE Encrypted Data | | | | | Object | | 16 | cose-encrypt0 | COSE_Encrypt0 | COSE Single Recipient | | | | | Encrypted Data Object | | 97 | cose-mac | COSE_Mac | COSE MACed Data Object | | 17 | cose-mac0 | COSE_Mac0 | COSE Mac w/o Recipients | | | | | Object | +-------+---------------+---------------+---------------------------+
Variables ¶
var ( AlgLabel = Label{Int64: 1} IvLabel = Label{Int64: 5} )
Common labels
+-----------+-------+----------------+-------------+----------------+ | Name | Label | Value Type | Value | Description | | | | | Registry | | +-----------+-------+----------------+-------------+----------------+ | alg | 1 | int / tstr | COSE | Cryptographic | | | | | Algorithms | algorithm to | | | | | registry | use | | --------- | ----- | -------------- | ----------- | -------------- | | crit | 2 | [+ label] | COSE Header | Critical | | | | | Parameters | headers to be | | | | | registry | understood | | --------- | ----- | -------------- | ----------- | -------------- | | content | 3 | tstr / uint | CoAP | Content type | | type | | | Content- | of the payload | | | | | Formats or | | | | | | Media Types | | | | | | registries | | | --------- | ----- | -------------- | ----------- | -------------- | | kid | 4 | bstr | | Key identifier | | --------- | ----- | -------------- | ----------- | -------------- | | IV | 5 | bstr | | Full | | | | | | Initialization | | | | | | Vector | | --------- | ----- | -------------- | ----------- | -------------- | | Partial | 6 | bstr | | Partial | | IV | | | | Initialization | | | | | | Vector | | --------- | ----- | -------------- | ----------- | -------------- | | counter | 7 | COSE_Signature | | CBOR-encoded | | signature | | / [+ | | signature | | | | COSE_Signature | | structure | | | | ] | | | +-----------+-------+----------------+-------------+----------------+
var ( KeyTypeKeyLabel = KeyLabel{Int64: 1} KeyIDKeyLabel = KeyLabel{Int64: 2} AlgKeyLabel = KeyLabel{Int64: 3} KeyOpsKeyLabel = KeyLabel{Int64: 4} BaseIVKeyLabel = KeyLabel{Int64: 5} )
Commmon Parameters
+---------+-------+----------------+------------+-------------------+ | Name | Label | CBOR Type | Value | Description | | | | | Registry | | +---------+-------+----------------+------------+-------------------+ | kty | 1 | tstr / int | COSE Key | Identification of | | | | | Common | the key type | | | | | Parameters | | | | | | | | | kid | 2 | bstr | | Key | | | | | | identification | | | | | | value -- match to | | | | | | kid in message | | | | | | | | alg | 3 | tstr / int | COSE | Key usage | | | | | Algorithms | restriction to | | | | | | this algorithm | | | | | | | | key_ops | 4 | [+ (tstr/int)] | | Restrict set of | | | | | | permissible | | | | | | operations | | | | | | | | Base IV | 5 | bstr | | Base IV to be | | | | | | xor-ed with | | | | | | Partial IVs | +---------+-------+----------------+------------+-------------------+
var ( OKPKeyType = KeyType{Int64: 1} EC2KeyType = KeyType{Int64: 2} SymmetricKeyType = KeyType{Int64: 4} )
+-----------+-------+-----------------------------------------------+ | Name | Value | Description | +-----------+-------+-----------------------------------------------+ | OKP | 1 | Octet Key Pair | | EC2 | 2 | Elliptic Curve Keys w/ x- and y-coordinate | | | | pair | | Symmetric | 4 | Symmetric Keys | | Reserved | 0 | This value is reserved | +-----------+-------+-----------------------------------------------+
Functions ¶
func RegisterEncryptAlgorithm ¶
func RegisterEncryptAlgorithm(alg EncryptAlgorithm, ad bool, keyBits uint16, f func([]byte) (Crypter, error))
RegisterEncryptAlgorithm adds a new encryption algorithm for use in this library. This function should be called in an init func.
func RegisterMacAlgorithm ¶
RegisterMacAlgorithm adds a new mac algorithm for use in this library. This function should be called in an init func.
func RegisterSignatureAlgorithm ¶
func RegisterSignatureAlgorithm(alg SignatureAlgorithm, f func() crypto.Hash)
RegisterSignatureAlgorithm adds a new signature algorithm for use in this library. This function should be called in an init func.
Types ¶
type Crypter ¶
type Crypter interface { // Encrypt converts plaintext and additional authenticated data to // ciphertext using the implementer's key and cipher. // // The unprotected headers of the outgoing structure are returned in order // for data such as IVs for block mode ciphers to be added. // // The value of additionalData will be nil if no AAD was provided and be // non-nil (and non-zero length, due to additional data COSE adds) if it // was provided. Encrypt(rand io.Reader, plaintext, additionalData []byte) (ciphertext []byte, unprotected HeaderMap, err error) // Decrypt converts ciphertext and additional authenticated data to // plaintext using the implementer's key and cipher. the unprotected // headers of the incoming structure are provided for optionally reading in // unprotected data, such as an IV, which the cipher may need as input. // // The value of additionalData will be nil if no AAD was provided and be // non-nil (and non-zero length, due to additional data COSE adds) if it // was provided. Decrypt(rand io.Reader, ciphertext, additionalData []byte, unprotected HeaderParser) (plaintext []byte, err error) }
Crypter uses a given key and cipher to encypt and decrypt data.
type Encrypt0 ¶
type Encrypt0[P, A any] struct { Header `cbor:",flat2"` Ciphertext *[]byte // byte string or null when transported separately }
Encrypt0 holds the encrypted content of an enveloped structure. It assumes contains no recipient information and therefore assumes that the recipient of the object will already know the identity of the key to be used in order to decrypt the message.
func (Encrypt0[P, A]) Decrypt ¶
func (e0 Encrypt0[P, A]) Decrypt(alg EncryptAlgorithm, key []byte, aad *A) (*P, error)
Decrypt a payload from the Ciphertext field, automatically unmarshaling it to type P.
For encryption algorithms that do not take external additional authenticated data, aad must be nil. To pass no AAD to an AEAD, E should be []byte and aad should be either nil or a pointer to an empty byte slice.
func (*Encrypt0[P, A]) Encrypt ¶
func (e0 *Encrypt0[P, A]) Encrypt(alg EncryptAlgorithm, key []byte, payload P, aad *A) error
Encrypt a payload, setting the Chiphertext field value.
The payload accepted is any type P, which will be marshaled to CBOR and if not already a CBOR byte string, then wrapped in one. The external AAD will be type A and the same marshaling rules apply.
For encryption algorithms that do not take external additional authenticated data, aad must be nil. To pass no AAD to an AEAD, E should be []byte and aad should be either nil or a pointer to an empty byte slice.
func (Encrypt0[P, A]) Tag ¶
func (e0 Encrypt0[P, A]) Tag() *Encrypt0Tag[P, A]
Tag is a helper for converting to a tag value.
type Encrypt0Tag ¶
Encrypt0Tag encodes to a CBOR tag while ensuring the right tag number.
func (Encrypt0Tag[P, A]) MarshalCBOR ¶
func (t Encrypt0Tag[P, A]) MarshalCBOR() ([]byte, error)
MarshalCBOR implements cbor.Marshaler.
func (*Encrypt0Tag[P, A]) UnmarshalCBOR ¶
func (t *Encrypt0Tag[P, A]) UnmarshalCBOR(data []byte) error
UnmarshalCBOR implements cbor.Unmarshaler.
func (Encrypt0Tag[P, A]) Untag ¶
func (t Encrypt0Tag[P, A]) Untag() *Encrypt0[P, A]
Untag is a helper for accessing the tag value.
type EncryptAlgorithm ¶
type EncryptAlgorithm int64
EncryptAlgorithm is the encryption type.
const ( A128GCM EncryptAlgorithm = 1 A192GCM EncryptAlgorithm = 2 A256GCM EncryptAlgorithm = 3 )
AES-GCM Algorithm Values
+---------+-------+------------------------------------------+ | Name | Value | Description | +---------+-------+------------------------------------------+ | A128GCM | 1 | AES-GCM mode w/ 128-bit key, 128-bit tag | | A192GCM | 2 | AES-GCM mode w/ 192-bit key, 128-bit tag | | A256GCM | 3 | AES-GCM mode w/ 256-bit key, 128-bit tag | +---------+-------+------------------------------------------+
const ( AesCcm16_64_128 EncryptAlgorithm = 10 AesCcm16_64_256 EncryptAlgorithm = 11 AesCcm64_64_128 EncryptAlgorithm = 12 AesCcm64_64_256 EncryptAlgorithm = 13 AesCcm16_128_128 EncryptAlgorithm = 30 AesCcm16_128_256 EncryptAlgorithm = 31 AesCcm64_128_128 EncryptAlgorithm = 32 AesCcm64_128_256 EncryptAlgorithm = 33 )
AES-CCM Algorithm Values
+--------------------+-------+----+-----+-----+---------------------+ | Name | Value | L | M | k | Description | +--------------------+-------+----+-----+-----+---------------------+ | AES-CCM-16-64-128 | 10 | 16 | 64 | 128 | AES-CCM mode | | | | | | | 128-bit key, 64-bit | | | | | | | tag, 13-byte nonce | | AES-CCM-16-64-256 | 11 | 16 | 64 | 256 | AES-CCM mode | | | | | | | 256-bit key, 64-bit | | | | | | | tag, 13-byte nonce | | AES-CCM-64-64-128 | 12 | 64 | 64 | 128 | AES-CCM mode | | | | | | | 128-bit key, 64-bit | | | | | | | tag, 7-byte nonce | | AES-CCM-64-64-256 | 13 | 64 | 64 | 256 | AES-CCM mode | | | | | | | 256-bit key, 64-bit | | | | | | | tag, 7-byte nonce | | AES-CCM-16-128-128 | 30 | 16 | 128 | 128 | AES-CCM mode | | | | | | | 128-bit key, | | | | | | | 128-bit tag, | | | | | | | 13-byte nonce | | AES-CCM-16-128-256 | 31 | 16 | 128 | 256 | AES-CCM mode | | | | | | | 256-bit key, | | | | | | | 128-bit tag, | | | | | | | 13-byte nonce | | AES-CCM-64-128-128 | 32 | 64 | 128 | 128 | AES-CCM mode | | | | | | | 128-bit key, | | | | | | | 128-bit tag, 7-byte | | | | | | | nonce | | AES-CCM-64-128-256 | 33 | 64 | 128 | 256 | AES-CCM mode | | | | | | | 256-bit key, | | | | | | | 128-bit tag, 7-byte | | | | | | | nonce | +--------------------+-------+----+-----+-----+---------------------+
const ( A128CTR EncryptAlgorithm = -65534 A192CTR EncryptAlgorithm = -65533 A256CTR EncryptAlgorithm = -65532 )
AES-CTR Algorithm Values
+=========+========+==========+=============+=============+ | Name | Value | Key Size | Description | Recommended | +=========+========+==========+=============+=============+ | A128CTR | -65534 | 128 | AES-CTR w/ | Deprecated | | | | | 128-bit key | | +---------+--------+----------+-------------+-------------+ | A192CTR | -65533 | 192 | AES-CTR w/ | Deprecated | | | | | 192-bit key | | +---------+--------+----------+-------------+-------------+ | A256CTR | -65532 | 256 | AES-CTR w/ | Deprecated | | | | | 256-bit key | | +---------+--------+----------+-------------+-------------+
const ( A128CBC EncryptAlgorithm = -65531 A192CBC EncryptAlgorithm = -65530 A256CBC EncryptAlgorithm = -65529 )
AES-CBC Algorithm Values
+=========+========+==========+=============+=============+ | Name | Value | Key Size | Description | Recommended | +=========+========+==========+=============+=============+ | A128CBC | -65531 | 128 | AES-CBC w/ | Deprecated | | | | | 128-bit key | | +---------+--------+----------+-------------+-------------+ | A192CBC | -65530 | 192 | AES-CBC w/ | Deprecated | | | | | 192-bit key | | +---------+--------+----------+-------------+-------------+ | A256CBC | -65529 | 256 | AES-CBC w/ | Deprecated | | | | | 256-bit key | | +---------+--------+----------+-------------+-------------+
func (EncryptAlgorithm) KeySize ¶
func (alg EncryptAlgorithm) KeySize() uint16
KeySize returns the key length in bytes that the algorithm requires.
func (EncryptAlgorithm) NewCrypter ¶
func (alg EncryptAlgorithm) NewCrypter(key []byte) (Crypter, error)
NewCrypter returns a new Crypter for the given encryption algorithm.
func (EncryptAlgorithm) SupportsAD ¶
func (alg EncryptAlgorithm) SupportsAD() bool
SupportsAD reports whether the algorithm supports additional authenticated data.
type Header ¶
Header is a type for embedding protected and unprotected headers into many COSE structures.
func (Header) FlatMarshalCBOR ¶
FlatMarshalCBOR implements cbor.FlatMarshaler.
type HeaderMap ¶
HeaderMap is used for protected and unprotected headers, which must have an int or string key and any value.
func (HeaderMap) Parse ¶
Parse is a helper to get values from the header map as the expected type. Because a HeaderMap unmarshals values to an any interface, their type follows the rules of the CBOR unmarshaler. Parse marshals a value back to CBOR and then unmarshals it into the provided pointer type v.
type HeaderParser ¶
type HeaderParser interface { // Parse gets values from the header map as the expected type. v must be a // pointer type, where the underlying value will be set. Parse(l Label, v any) (bool, error) }
HeaderParser decodes headers and is a read-only interface.
type IntOrStr ¶
IntOrStr is either an int or a text string. Many values in COSE have this polymorphic type. For simplicity, it is implemented once and each type is an alias or embeds it.
func (IntOrStr) MarshalCBOR ¶
MarshalCBOR implements cbor.Marshaler.
func (*IntOrStr) UnmarshalCBOR ¶
UnmarshalCBOR implements cbor.Unmarshaler.
type Key ¶
Key is a COSE structure built on a CBOR map object.
The element "kty" is a required element in a COSE_Key map.
CDDL:
COSE_Key = { 1 => tstr / int, ; kty ? 2 => bstr, ; kid ? 3 => tstr / int, ; alg ? 4 => [+ (tstr / int) ], ; key_ops ? 5 => bstr, ; Base IV * label => values }
func (Key) Alg ¶
Alg returns the algorithm value. It returns false if the value is missing or not a valid type.
func (Key) BaseIV ¶
BaseIV returns the base IV value. It returns false if the value is missing or not a valid type.
func (Key) IsEllipticCurveKey ¶
IsEllipticCurveKey returns whether the key type is an elliptic curve key.
func (Key) IsOctetKeyPair ¶
IsOctetKeyPair returns whether the key type is an octet key pair.
func (Key) IsSymmetricKey ¶
IsSymmetricKey returns whether the key type is a symmetric key..
func (Key) KeyOps ¶
KeyOps returns the key ops value. It returns false if the value is missing or not a valid type.
func (Key) Kid ¶
Kid returns the key ID value. It returns false if the value is missing or not a valid type.
func (Key) Kty ¶
Kty returns the key type value. It returns false if the value is missing or not a valid type.
func (Key) MarshalCBOR ¶
MarshalCBOR implements cbor.Marshaler.
func (*Key) UnmarshalCBOR ¶
UnmarshalCBOR implements cbor.Unmarshaler.
type KeyLabel ¶
type KeyLabel = IntOrStr
KeyLabel is an int or string, used in the Key structure map.
type KeyType ¶
type KeyType = IntOrStr
KeyType is an int or string, used for the "kty" value in the Key structure map.
type Label ¶
type Label = IntOrStr
Label is used for [HeaderMap]s and can be either an int64 or a string.
type Mac0 ¶
type Mac0[P, A any] struct { Header `cbor:",flat2"` Payload *cbor.ByteWrap[P] // null when transported separately Value []byte // non-empty byte string containing the MAC }
Mac0 is a message authentication code structure that is used when the recipient structure is not needed, because the key to be used is implicitly known.
type Mac0Tag ¶
Mac0Tag encodes to a CBOR tag while ensuring the right tag number.
func (Mac0Tag[P, A]) MarshalCBOR ¶
MarshalCBOR implements cbor.Marshaler.
func (*Mac0Tag[P, A]) UnmarshalCBOR ¶
UnmarshalCBOR implements cbor.Unmarshaler.
type MacAlgorithm ¶
type MacAlgorithm int64
MacAlgorithm is the MAC type.
const ( HMac256_64 MacAlgorithm = 4 HMac256 MacAlgorithm = 5 HMac384 MacAlgorithm = 6 HMac512 MacAlgorithm = 7 )
HMAC Algorithm Values
+-----------+-------+---------+----------+--------------------------+ | Name | Value | Hash | Tag | Description | | | | | Length | | +-----------+-------+---------+----------+--------------------------+ | HMAC | 4 | SHA-256 | 64 | HMAC w/ SHA-256 | | 256/64 | | | | truncated to 64 bits | | HMAC | 5 | SHA-256 | 256 | HMAC w/ SHA-256 | | 256/256 | | | | | | HMAC | 6 | SHA-384 | 384 | HMAC w/ SHA-384 | | 384/384 | | | | | | HMAC | 7 | SHA-512 | 512 | HMAC w/ SHA-512 | | 512/512 | | | | | +-----------+-------+---------+----------+--------------------------+
const ( AesCbcMac128_64 MacAlgorithm = 14 AesCbcMac256_64 MacAlgorithm = 15 AesCbcMac128_128 MacAlgorithm = 25 AesCbcMac256_128 MacAlgorithm = 26 )
AES-CBC-MAC Algorithm Values
+-------------+-------+----------+----------+-----------------------+ | Name | Value | Key | Tag | Description | | | | Length | Length | | +-------------+-------+----------+----------+-----------------------+ | AES-MAC | 14 | 128 | 64 | AES-MAC 128-bit key, | | 128/64 | | | | 64-bit tag | | AES-MAC | 15 | 256 | 64 | AES-MAC 256-bit key, | | 256/64 | | | | 64-bit tag | | AES-MAC | 25 | 128 | 128 | AES-MAC 128-bit key, | | 128/128 | | | | 128-bit tag | | AES-MAC | 26 | 256 | 128 | AES-MAC 256-bit key, | | 256/128 | | | | 128-bit tag | +-------------+-------+----------+----------+-----------------------+
func (MacAlgorithm) KeySize ¶
func (alg MacAlgorithm) KeySize() uint16
KeySize returns the key length in bytes that the algorithm requires. While HMac algorithms can handle keys of different sizes, the recommended lengths are required by this package: 128 bits for SHA256 and 256 bits for SHA512 family.
type RFC8152Signer ¶
RFC8152Signer wraps an ECDSA private key and uses the signature encoding required by COSE.
func (RFC8152Signer) Sign ¶
func (key RFC8152Signer) Sign(rand io.Reader, digest []byte, _ crypto.SignerOpts) ([]byte, error)
Sign implements crypto.Signer.
type Sign1 ¶
type Sign1[P, A any] struct { Header `cbor:",flat2"` Payload *cbor.ByteWrap[P] // non-empty byte string or null Signature []byte // non-empty byte string }
Sign1 is a COSE_Sign1 signature structure, which is used when only one signature is being placed on a message.
func (*Sign1[P, A]) Sign ¶
func (s1 *Sign1[P, A]) Sign(key crypto.Signer, payload *P, additionalData A, opts crypto.SignerOpts) error
Sign using a single private key. Unless it was transported independently of the signature, payload may be nil. If no external AAD is supplied, the type should be []byte and the value nil.
For RSA keys, opts must either be type *rsa.PSSOptions with a SaltLength value of PSSSaltLengthEqualsHash or equivalent numerical value or a valid hash function for PKCS1 v1.5 signing.
type Sign1Tag ¶
Sign1Tag encodes to a CBOR tag while ensuring the right tag number.
func (Sign1Tag[P, A]) MarshalCBOR ¶
MarshalCBOR implements cbor.Marshaler.
func (*Sign1Tag[P, A]) UnmarshalCBOR ¶
UnmarshalCBOR implements cbor.Unmarshaler.
type SignatureAlgorithm ¶
type SignatureAlgorithm int64
SignatureAlgorithm is the ECDSA/RSASSA-PKCS1-v1_5/RSASSA-PKCS1-v1_5 signature type and hash.
const ( ES256Alg SignatureAlgorithm = -7 ES384Alg SignatureAlgorithm = -35 ES512Alg SignatureAlgorithm = -36 )
ECDSA Algorithm Values
+-------+-------+---------+------------------+ | Name | Value | Hash | Description | +-------+-------+---------+------------------+ | ES256 | -7 | SHA-256 | ECDSA w/ SHA-256 | | ES384 | -35 | SHA-384 | ECDSA w/ SHA-384 | | ES512 | -36 | SHA-512 | ECDSA w/ SHA-512 | +-------+-------+---------+------------------+
const ( RS256Alg SignatureAlgorithm = -257 RS384Alg SignatureAlgorithm = -258 RS512Alg SignatureAlgorithm = -259 )
RSASSA-PKCS1-v1_5 Algorithm Values
+-------+-------+---------+------------------------------+ | Name | Value | Hash | Description | +-------+-------+---------+------------------------------+ | RS256 | -257 | SHA-256 | RSASSA-PKCS1-v1_5 w/ SHA-256 | | RS384 | -258 | SHA-384 | RSASSA-PKCS1-v1_5 w/ SHA-384 | | RS512 | -259 | SHA-512 | RSASSA-PKCS1-v1_5 w/ SHA-512 | +-------+-------+---------+------------------------------+
const ( PS256Alg SignatureAlgorithm = -37 PS384Alg SignatureAlgorithm = -38 PS512Alg SignatureAlgorithm = -39 )
RSASSA-PSS Algorithm Values from RFC 8230
+-------+-------+---------+-------------+-----------------------+ | Name | Value | Hash | Salt Length | Description | +-------+-------+---------+-------------+-----------------------+ | PS256 | -37 | SHA-256 | 32 | RSASSA-PSS w/ SHA-256 | | PS384 | -38 | SHA-384 | 48 | RSASSA-PSS w/ SHA-384 | | PS512 | -39 | SHA-512 | 64 | RSASSA-PSS w/ SHA-512 | +-------+-------+---------+-------------+-----------------------+
func SignatureAlgorithmFor ¶
func SignatureAlgorithmFor(key crypto.PublicKey, opts crypto.SignerOpts) (SignatureAlgorithm, error)
SignatureAlgorithmFor returns the Signature Algorithm identifier for the given key and options.
func (SignatureAlgorithm) HashFunc ¶
func (alg SignatureAlgorithm) HashFunc() crypto.Hash
HashFunc implements crypto.SignerOpts.