-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MultiAlgorithmSigner allows to restrict client-side, server-side and certificate signing algorithms. Fixes golang/go#52132 Fixes golang/go#36261 Change-Id: I295092f1bba647327aaaf294f110e9157d294159 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/508398 Reviewed-by: Filippo Valsorda <[email protected]> Run-TryBot: Filippo Valsorda <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
- Loading branch information
Showing
9 changed files
with
554 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,9 @@ import ( | |
|
||
// Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear | ||
// in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms. | ||
// Unlike key algorithm names, these are not passed to AlgorithmSigner and don't | ||
// appear in the Signature.Format field. | ||
// Unlike key algorithm names, these are not passed to AlgorithmSigner nor | ||
// returned by MultiAlgorithmSigner and don't appear in the Signature.Format | ||
// field. | ||
const ( | ||
CertAlgoRSAv01 = "[email protected]" | ||
CertAlgoDSAv01 = "[email protected]" | ||
|
@@ -255,10 +256,17 @@ func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) { | |
return nil, errors.New("ssh: signer and cert have different public key") | ||
} | ||
|
||
if algorithmSigner, ok := signer.(AlgorithmSigner); ok { | ||
switch s := signer.(type) { | ||
case MultiAlgorithmSigner: | ||
return &multiAlgorithmSigner{ | ||
AlgorithmSigner: &algorithmOpenSSHCertSigner{ | ||
&openSSHCertSigner{cert, signer}, s}, | ||
supportedAlgorithms: s.Algorithms(), | ||
}, nil | ||
case AlgorithmSigner: | ||
return &algorithmOpenSSHCertSigner{ | ||
&openSSHCertSigner{cert, signer}, algorithmSigner}, nil | ||
} else { | ||
&openSSHCertSigner{cert, signer}, s}, nil | ||
default: | ||
return &openSSHCertSigner{cert, signer}, nil | ||
} | ||
} | ||
|
@@ -432,16 +440,30 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error { | |
} | ||
|
||
// SignCert signs the certificate with an authority, setting the Nonce, | ||
// SignatureKey, and Signature fields. | ||
// SignatureKey, and Signature fields. If the authority implements the | ||
// MultiAlgorithmSigner interface the first algorithm in the list is used. This | ||
// is useful if you want to sign with a specific algorithm. | ||
func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { | ||
c.Nonce = make([]byte, 32) | ||
if _, err := io.ReadFull(rand, c.Nonce); err != nil { | ||
return err | ||
} | ||
c.SignatureKey = authority.PublicKey() | ||
|
||
// Default to KeyAlgoRSASHA512 for ssh-rsa signers. | ||
if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA { | ||
if v, ok := authority.(MultiAlgorithmSigner); ok { | ||
if len(v.Algorithms()) == 0 { | ||
return errors.New("the provided authority has no signature algorithm") | ||
} | ||
// Use the first algorithm in the list. | ||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), v.Algorithms()[0]) | ||
if err != nil { | ||
return err | ||
} | ||
c.Signature = sig | ||
return nil | ||
} else if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA { | ||
// Default to KeyAlgoRSASHA512 for ssh-rsa signers. | ||
// TODO: consider using KeyAlgoRSASHA256 as default. | ||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512) | ||
if err != nil { | ||
return err | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.