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

Open
stoggi opened this issue Dec 24, 2019 · 4 comments
Open

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

stoggi opened this issue Dec 24, 2019 · 4 comments

Comments

@stoggi
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?

Yes

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

https://github.com/golang/crypto/blob/0a08dada0ff98d02f3864a23ae8d27cb8fba5303/ssh/certs.go#L417-L432

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.

https://play.golang.org/p/PYbYu6-9XY8

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

@toothrot toothrot commented Jan 7, 2020

@FiloSottile
Copy link
Member

@FiloSottile FiloSottile commented Jan 7, 2020

/cc @hanwen

@stoggi
Copy link
Author

@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.

https://play.golang.org/p/lywpKtapMeZ

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
}
@alex
Copy link
Contributor

@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: https://www.openssh.com/txt/release-8.2

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

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.