go.crypto/ssh: Add support for ECDSA keys and certs.
R=agl, dave
CC=golang-dev
https://golang.org/cl/6873060
diff --git a/ssh/certs.go b/ssh/certs.go
index 40cf706..eeaef31 100644
--- a/ssh/certs.go
+++ b/ssh/certs.go
@@ -9,17 +9,18 @@
import (
"crypto/dsa"
+ "crypto/ecdsa"
"crypto/rsa"
"time"
)
// String constants in [PROTOCOL.certkeys] for certificate algorithm names.
const (
- hostAlgoRSACertV01 = "ssh-rsa-cert-v01@openssh.com"
- hostAlgoDSACertV01 = "ssh-dss-cert-v01@openssh.com"
- hostAlgoECDSA256CertV01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
- hostAlgoECDSA384CertV01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
- hostAlgoECDSA521CertV01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
+ certAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
+ certAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
+ certAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
+ certAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
+ certAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
)
// Certificate types are used to specify whether a certificate is for identification
@@ -41,10 +42,12 @@
// An OpenSSHCertV01 represents an OpenSSH certificate as defined in
// [PROTOCOL.certkeys] rev 1.8. Supported formats include
-// ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com.
+// ssh-rsa-cert-v01@openssh.com, ssh-dss-cert-v01@openssh.com,
+// ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com,
+// and ecdsa-sha2-nistp521-cert-v01@openssh.com.
type OpenSSHCertV01 struct {
Nonce []byte
- Key interface{} // rsa or dsa *PublicKey
+ Key interface{} // rsa, dsa, or ecdsa *PublicKey
Serial uint64
Type uint32
KeyId string
@@ -65,18 +68,24 @@
}
switch algo {
- case hostAlgoRSACertV01:
+ case certAlgoRSAv01:
var rsaPubKey *rsa.PublicKey
if rsaPubKey, in, ok = parseRSA(in); !ok {
return
}
cert.Key = rsaPubKey
- case hostAlgoDSACertV01:
+ case certAlgoDSAv01:
var dsaPubKey *dsa.PublicKey
if dsaPubKey, in, ok = parseDSA(in); !ok {
return
}
cert.Key = dsaPubKey
+ case certAlgoECDSA256v01, certAlgoECDSA384v01, certAlgoECDSA521v01:
+ var ecdsaPubKey *ecdsa.PublicKey
+ if ecdsaPubKey, in, ok = parseECDSA(in); !ok {
+ return
+ }
+ cert.Key = ecdsaPubKey
default:
ok = false
return
@@ -149,6 +158,9 @@
case *dsa.PublicKey:
k := cert.Key.(*dsa.PublicKey)
pubKey = marshalPubDSA(k)
+ case *ecdsa.PublicKey:
+ k := cert.Key.(*ecdsa.PublicKey)
+ pubKey = marshalPubECDSA(k)
default:
panic("ssh: unknown public key type in cert")
}