|
5 | 5 | "crypto/ecdsa"
|
6 | 6 | "crypto/hmac"
|
7 | 7 | "crypto/rsa"
|
8 |
| - "crypto/sha1" |
9 | 8 | "crypto/sha256"
|
10 | 9 | "crypto/sha512"
|
11 | 10 | "crypto/subtle" // Use should trigger great care
|
@@ -68,10 +67,9 @@ var hashToDef = map[crypto.Hash]struct {
|
68 | 67 | // http://www.iana.org/assignments/signature-algorithms
|
69 | 68 | //
|
70 | 69 | // Note that the forbidden hashes have an invalid 'new' function.
|
71 |
| - crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }}, |
72 |
| - crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }}, |
73 |
| - // Temporarily enable SHA1 because of issue https://github.com/golang/go/issues/37278 |
74 |
| - crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return sha1.New(), nil }}, |
| 70 | + crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }}, |
| 71 | + crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }}, |
| 72 | + crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return nil, nil }}, |
75 | 73 | crypto.SHA224: {sha224String, func(key []byte) (hash.Hash, error) { return sha256.New224(), nil }},
|
76 | 74 | crypto.SHA256: {sha256String, func(key []byte) (hash.Hash, error) { return sha256.New(), nil }},
|
77 | 75 | crypto.SHA384: {sha384String, func(key []byte) (hash.Hash, error) { return sha512.New384(), nil }},
|
@@ -192,11 +190,49 @@ func (r *rsaAlgorithm) setSig(b []byte) error {
|
192 | 190 | return nil
|
193 | 191 | }
|
194 | 192 |
|
| 193 | +// Code from https://github.com/cloudtools/ssh-cert-authority/pull/49/files |
| 194 | +// This interface provides a way to reach the exported, but not accessible SignWithOpts() method |
| 195 | +// in x/crypto/ssh/agent. Access to this is needed to sign with more secure signing algorithms |
| 196 | +type agentKeyringSigner interface { |
| 197 | + SignWithOpts(rand io.Reader, data []byte, opts crypto.SignerOpts) (*ssh.Signature, error) |
| 198 | +} |
| 199 | + |
| 200 | +// A struct to wrap an SSH Signer with one that will switch to SHA256 Signatures. |
| 201 | +// Replaces the call to Sign() with a call to SignWithOpts using HashFunc() algorithm. |
| 202 | +type Sha256Signer struct { |
| 203 | + ssh.Signer |
| 204 | +} |
| 205 | + |
| 206 | +func (s Sha256Signer) HashFunc() crypto.Hash { |
| 207 | + return crypto.SHA256 |
| 208 | +} |
| 209 | + |
| 210 | +func (s Sha256Signer) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) { |
| 211 | + if aks, ok := s.Signer.(agentKeyringSigner); !ok { |
| 212 | + return nil, fmt.Errorf("ssh: can't wrap a non ssh agentKeyringSigner") |
| 213 | + } else { |
| 214 | + return aks.SignWithOpts(rand, data, s) |
| 215 | + } |
| 216 | +} |
| 217 | + |
195 | 218 | func (r *rsaAlgorithm) Sign(rand io.Reader, p crypto.PrivateKey, sig []byte) ([]byte, error) {
|
196 | 219 | if r.sshSigner != nil {
|
197 |
| - sshsig, err := r.sshSigner.Sign(rand, sig) |
198 |
| - if err != nil { |
199 |
| - return nil, err |
| 220 | + var ( |
| 221 | + sshsig *ssh.Signature |
| 222 | + err error |
| 223 | + ) |
| 224 | + // are we using an SSH Agent |
| 225 | + if _, ok := r.sshSigner.(agentKeyringSigner); ok { |
| 226 | + signer := Sha256Signer{r.sshSigner} |
| 227 | + sshsig, err = signer.Sign(rand, sig) |
| 228 | + if err != nil { |
| 229 | + return nil, err |
| 230 | + } |
| 231 | + } else { |
| 232 | + sshsig, err = r.sshSigner.(ssh.AlgorithmSigner).SignWithAlgorithm(rand, sig, ssh.SigAlgoRSASHA2256) |
| 233 | + if err != nil { |
| 234 | + return nil, err |
| 235 | + } |
200 | 236 | }
|
201 | 237 |
|
202 | 238 | return sshsig.Blob, nil
|
|
0 commit comments