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