Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/crypto/ssh: cannot sign certificate with different algorithm #36261

stoggi opened this issue Dec 24, 2019 · 4 comments

x/crypto/ssh: cannot sign certificate with different algorithm #36261

stoggi opened this issue Dec 24, 2019 · 4 comments


Copy link

@stoggi stoggi commented Dec 24, 2019

What version of Go are you using (go version)?

$ go version
go version go1.13.4 darwin/amd64

Does this issue reproduce with the latest release?


What operating system and processor architecture are you using (go env)?

go env Output
$ go env
not relevant

What did you do?

I want to be able to change the algorithm used when signing an SSH certificate. Specifically with a private key implemented in hardware with ssh.NewSignerFromSigner.

What did you expect to see?

I should be able to pass an AlgorithmSigner interface, and specify which algorithm to use when invoking Certificate.SignCert

What did you see instead?

When signing a certificate with Certificate.SignCert I can not specify the algorithm used.

I am happy to contribute a change to fix this. I propose adding a new method to the Certificate struct, named SignCertWithAlgorithm which correctly calls authority.SignWithAlgorithm.

I've put together a short proof-of-concept implementing SignCertWithAlgorithm and adding a new private method prepareForSigning to keep the nonce generation in once place.

@gopherbot gopherbot added this to the Unreleased milestone Dec 24, 2019
Copy link

@toothrot toothrot commented Jan 7, 2020

Copy link

@FiloSottile FiloSottile commented Jan 7, 2020

/cc @hanwen

Copy link

@stoggi stoggi commented Jan 12, 2020

An alternative implementation would be to create a NewAlgorithmSignerFromSigner method to return a signer interface, that can sign with a particular algorithm. Then you could pass it to Certificate.SignCert normally.

type sshAlgorithmSigner struct {
	algorithm string
	signer    ssh.AlgorithmSigner

func (s *sshAlgorithmSigner) PublicKey() ssh.PublicKey {
	return s.signer.PublicKey()

func (s *sshAlgorithmSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) {
	return s.signer.SignWithAlgorithm(rand, data, s.algorithm)

func NewAlgorithmSignerFromSigner(signer crypto.Signer, algorithm string) (ssh.Signer, error) {
	sshSigner, err := ssh.NewSignerFromSigner(signer)
	if err != nil {
		return nil, err
	algorithmSigner, ok := sshSigner.(ssh.AlgorithmSigner)
	if !ok {
		return nil, errors.New("unable to cast to ssh.AlgorithmSigner")
	s := sshAlgorithmSigner{
		signer:    algorithmSigner,
		algorithm: algorithm,
	return &s, nil
Copy link

@alex alex commented Feb 14, 2020

A particular urgency for this issue is that right now with an RSA private key, the default is SHA-1. OpenSSH 8.2 has removed support for RSA-SHA1 signatures on certificates:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants