Keyboard Shortcuts

File
u :up to issue
m :publish + mail comments
M :edit review message
j / k :jump to file after / before current file
J / K :jump to next file with a comment after / before current file
Side-by-side diff
i :toggle intra-line diffs
e :expand all comments
c :collapse all comments
s :toggle showing all comments
n / p :next / previous diff chunk or comment
N / P :next / previous comment
<Up> / <Down> :next / previous line
<Enter> :respond to / edit current comment
d :mark current comment as done
Issue
u :up to list of issues
m :publish + mail comments
j / k :jump to patch after / before current patch
o / <Enter> :open current patch in side-by-side view
i :open current patch in unified diff view
Issue List
j / k :jump to issue after / before current issue
o / <Enter> :open current issue
# : close issue
Comment/message editing
<Ctrl> + s or <Ctrl> + Enter :save comment
<Esc> :cancel edit
Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(262)
Issues Repositories Search
Open Issues | Closed Issues | All Issues | Sign in with your Google Account to create issues and add comments

Delta Between Two Patch Sets: ssh/keys.go

Issue 96860043: go.crypto/ssh: Introduce key registration and refactor ...
Left Patch Set: Created 11 years, 8 months ago
Right Patch Set: diff -r 5478be1963aa https://code.google.com/p/go.crypto Created 11 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « ssh/certs.go ('k') | no next file » | no next file with change/comment »
('i') | ('e') | ('c') | ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2012 The Go Authors. All rights reserved. 1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package ssh 5 package ssh
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "crypto" 9 "crypto"
10 "crypto/dsa" 10 "crypto/dsa"
11 "crypto/ecdsa" 11 "crypto/ecdsa"
12 "crypto/elliptic" 12 "crypto/elliptic"
13 "crypto/rsa" 13 "crypto/rsa"
14 "crypto/x509" 14 "crypto/x509"
15 "encoding/asn1" 15 "encoding/asn1"
16 "encoding/base64" 16 "encoding/base64"
17 "encoding/pem" 17 "encoding/pem"
18 "errors" 18 "errors"
19 "fmt" 19 "fmt"
20 "io" 20 "io"
21 "math/big" 21 "math/big"
22 "sync"
22 ) 23 )
23 24
24 // These constants represent the algorithm names for key types supported by this 25 // These constants represent the algorithm names for key types supported by this
25 // package. 26 // package.
26 const ( 27 const (
27 KeyAlgoRSA = "ssh-rsa" 28 KeyAlgoRSA = "ssh-rsa"
28 KeyAlgoDSA = "ssh-dss" 29 KeyAlgoDSA = "ssh-dss"
29 KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" 30 KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
30 KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" 31 KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
31 KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" 32 KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
32 ) 33 )
33 34
35 func init() {
36 registerPubKeyType(KeyAlgoRSA, parseRSA)
37 registerPubKeyType(KeyAlgoDSA, parseDSA)
38 registerPubKeyType(KeyAlgoECDSA256, parseECDSA)
39 registerPubKeyType(KeyAlgoECDSA384, parseECDSA)
40 registerPubKeyType(KeyAlgoECDSA521, parseECDSA)
41 registerPubKeyType(CertAlgoRSAv01, parseCert)
42 registerPubKeyType(CertAlgoDSAv01, parseCert)
43 registerPubKeyType(CertAlgoECDSA256v01, parseCert)
44 registerPubKeyType(CertAlgoECDSA384v01, parseCert)
45 registerPubKeyType(CertAlgoECDSA521v01, parseCert)
46 }
47
34 // parsePubKey parses a public key of the given algorithm. 48 // parsePubKey parses a public key of the given algorithm.
35 // Use ParsePublicKey for keys with prepended algorithm. 49 // Use ParsePublicKey for keys with prepended algorithm.
36 func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err or) { 50 func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err or) {
37 » switch algo { 51 » regKeyMu.RLock()
38 » case KeyAlgoRSA: 52 » parser := supportedKeys[algo]
39 » » return parseRSA(in) 53 » regKeyMu.RUnlock()
40 » case KeyAlgoDSA: 54 » if parser == nil {
41 » » return parseDSA(in) 55 » » return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %q", al go)
42 » case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: 56 » }
43 » » return parseECDSA(in) 57 » return parser(algo, in)
44 » case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA3 84v01, CertAlgoECDSA521v01:
45 » » cert, err := parseCert(in, certToPrivAlgo(algo))
46 » » if err != nil {
47 » » » return nil, nil, err
48 » » }
49 » » return cert, nil, nil
50 » }
51 » return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", err)
52 } 58 }
53 59
54 // parseAuthorizedKey parses a public key in OpenSSH authorized_keys format 60 // parseAuthorizedKey parses a public key in OpenSSH authorized_keys format
55 // (see sshd(8) manual page) once the options and key type fields have been 61 // (see sshd(8) manual page) once the options and key type fields have been
56 // removed. 62 // removed.
57 func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) { 63 func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
58 in = bytes.TrimSpace(in) 64 in = bytes.TrimSpace(in)
59 65
60 i := bytes.IndexAny(in, " \t") 66 i := bytes.IndexAny(in, " \t")
61 if i == -1 { 67 if i == -1 {
(...skipping 150 matching lines...) | | Loading...
212 Sign(rand io.Reader, data []byte) (*Signature, error) 218 Sign(rand io.Reader, data []byte) (*Signature, error)
213 } 219 }
214 220
215 type rsaPublicKey rsa.PublicKey 221 type rsaPublicKey rsa.PublicKey
216 222
217 func (r *rsaPublicKey) Type() string { 223 func (r *rsaPublicKey) Type() string {
218 return "ssh-rsa" 224 return "ssh-rsa"
219 } 225 }
220 226
221 // parseRSA parses an RSA key according to RFC 4253, section 6.6. 227 // parseRSA parses an RSA key according to RFC 4253, section 6.6.
222 func parseRSA(in []byte) (out PublicKey, rest []byte, err error) { 228 func parseRSA(algo string, in []byte) (out PublicKey, rest []byte, err error) {
223 var w struct { 229 var w struct {
224 E *big.Int 230 E *big.Int
225 N *big.Int 231 N *big.Int
226 Rest []byte `ssh:"rest"` 232 Rest []byte `ssh:"rest"`
227 } 233 }
228 if err := Unmarshal(in, &w); err != nil { 234 if err := Unmarshal(in, &w); err != nil {
229 return nil, nil, err 235 return nil, nil, err
230 } 236 }
231 237
232 if w.E.BitLen() > 24 { 238 if w.E.BitLen() > 24 {
(...skipping 56 matching lines...) | | Loading...
289 }, nil 295 }, nil
290 } 296 }
291 297
292 type dsaPublicKey dsa.PublicKey 298 type dsaPublicKey dsa.PublicKey
293 299
294 func (r *dsaPublicKey) Type() string { 300 func (r *dsaPublicKey) Type() string {
295 return "ssh-dss" 301 return "ssh-dss"
296 } 302 }
297 303
298 // parseDSA parses an DSA key according to RFC 4253, section 6.6. 304 // parseDSA parses an DSA key according to RFC 4253, section 6.6.
299 func parseDSA(in []byte) (out PublicKey, rest []byte, err error) { 305 func parseDSA(algo string, in []byte) (out PublicKey, rest []byte, err error) {
300 var w struct { 306 var w struct {
301 P, Q, G, Y *big.Int 307 P, Q, G, Y *big.Int
302 Rest []byte `ssh:"rest"` 308 Rest []byte `ssh:"rest"`
303 } 309 }
304 if err := Unmarshal(in, &w); err != nil { 310 if err := Unmarshal(in, &w); err != nil {
305 return nil, nil, err 311 return nil, nil, err
306 } 312 }
307 313
308 key := &dsaPublicKey{ 314 key := &dsaPublicKey{
309 Parameters: dsa.Parameters{ 315 Parameters: dsa.Parameters{
(...skipping 104 matching lines...) | | Loading...
414 switch { 420 switch {
415 case bitSize <= 256: 421 case bitSize <= 256:
416 return crypto.SHA256 422 return crypto.SHA256
417 case bitSize <= 384: 423 case bitSize <= 384:
418 return crypto.SHA384 424 return crypto.SHA384
419 } 425 }
420 return crypto.SHA512 426 return crypto.SHA512
421 } 427 }
422 428
423 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. 429 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
424 func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) { 430 func parseECDSA(algo string, in []byte) (out PublicKey, rest []byte, err error) {
425 identifier, in, ok := parseString(in) 431 identifier, in, ok := parseString(in)
426 if !ok { 432 if !ok {
427 return nil, nil, errShortRead 433 return nil, nil, errShortRead
428 } 434 }
429 435
430 key := new(ecdsa.PublicKey) 436 key := new(ecdsa.PublicKey)
431 437
432 switch string(identifier) { 438 switch string(identifier) {
433 case "nistp256": 439 case "nistp256":
434 key.Curve = elliptic.P256() 440 key.Curve = elliptic.P256()
(...skipping 184 matching lines...) | | Loading...
619 Parameters: dsa.Parameters{ 625 Parameters: dsa.Parameters{
620 P: k.P, 626 P: k.P,
621 Q: k.Q, 627 Q: k.Q,
622 G: k.G, 628 G: k.G,
623 }, 629 },
624 Y: k.Priv, 630 Y: k.Priv,
625 }, 631 },
626 X: k.Pub, 632 X: k.Pub,
627 }, nil 633 }, nil
628 } 634 }
635
636 // TODO(jmpittman): This is a step toward improving pluggability into the ssh
637 // package. Later on, remember to export what is necessary when that
638 // pluggability becomes reality and we can move a lot of functionality for
639 // specific kinds of keys to outside of this package.
640 var regKeyMu sync.RWMutex
641
642 var supportedKeys = map[string]pubKeyParser{}
643
644 type pubKeyParser func(algo string, in []byte) (pubKey PublicKey, rest []byte, e rr error)
645
646 func registerPubKeyType(algo string, parser pubKeyParser) {
647 regKeyMu.Lock()
648 supportedKeys[algo] = parser
649 regKeyMu.Unlock()
650 }
LEFTRIGHT
« ssh/certs.go ('k') | no next file » | ('i') | ('e') | ('c') | ('s')
Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b

AltStyle によって変換されたページ (->オリジナル) /