Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2826)

Side by Side Diff: ssh/keys.go

Issue 6855107: code review 6855107: ssh: add functions for public keys in wire & auth keys ...
Patch Set: diff -r b2b2ae1f5140 https://code.google.com/p/go.crypto Created 11 years, 4 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:
View unified diff | Download patch
« no previous file with comments | « no previous file | ssh/test/keys_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "crypto/dsa" 9 "crypto/dsa"
9 "crypto/rsa" 10 "crypto/rsa"
11 "encoding/base64"
10 "math/big" 12 "math/big"
13 "strings"
14 )
15
16 // Keytypes supported by OpenSSH 1.5.9
agl1 2012/11/30 22:36:45 1.5.9? Maybe 5.9?
17 const (
18 keyAlgoRSA = "ssh-rsa"
19 keyAlgoDSA = "ssh-dss"
20 keyAlgoECDSA256 = "ecdsa-sha2-nistp256"
21 keyAlgoECDSA384 = "ecdsa-sha2-nistp384"
22 keyAlgoECDSA521 = "ecdsa-sha2-nistp521"
11 ) 23 )
12 24
13 // parsePubKey parses a public key according to RFC 4253, section 6.6. 25 // parsePubKey parses a public key according to RFC 4253, section 6.6.
14 func parsePubKey(in []byte) (out interface{}, rest []byte, ok bool) { 26 func parsePubKey(in []byte) (out interface{}, rest []byte, ok bool) {
15 algo, in, ok := parseString(in) 27 algo, in, ok := parseString(in)
16 if !ok { 28 if !ok {
17 return 29 return
18 } 30 }
19 31
20 switch string(algo) { 32 switch string(algo) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 length += intLength(key.Y) 123 length += intLength(key.Y)
112 124
113 ret := make([]byte, length) 125 ret := make([]byte, length)
114 r := marshalInt(ret, key.P) 126 r := marshalInt(ret, key.P)
115 r = marshalInt(r, key.Q) 127 r = marshalInt(r, key.Q)
116 r = marshalInt(r, key.G) 128 r = marshalInt(r, key.G)
117 marshalInt(r, key.Y) 129 marshalInt(r, key.Y)
118 130
119 return ret 131 return ret
120 } 132 }
133
134 // ParseAuthorizedKeys parses a public key from an authorized_keys
135 // file used in OpenSSH according to the sshd(8) manual page.
136 func ParseAuthorizedKey(in []byte) (out interface{}, comment string, options []s tring, rest []byte, ok bool) {
137 for {
138 end := bytes.IndexByte(in, '\n')
139 if end != -1 {
140 rest = in[end+1:]
141 in = in[:end]
142 } else {
143 rest = nil
144 }
145
146 end = bytes.IndexByte(in, '\r')
147 if end != -1 {
148 in = in[:end]
149 }
150
151 in = bytes.TrimSpace(in)
152 if len(in) != 0 && !bytes.HasPrefix(in, []byte("#")) {
agl1 2012/11/30 22:36:45 replace !bytes.HasPrefix(in, []byte("#")) with
153 break
154 }
155 in = rest
156 }
157
158 // fields: options, keytype, base64key, comment
159 // options & comment are optional
160 fields := strings.Fields(string(in))
161 if len(fields) < 2 {
162 return nil, "", nil, rest, false
163 }
164 var b64key string
165
166 switch fields[0] {
167 case keyAlgoRSA, keyAlgoDSA:
168 options = nil
169 b64key = fields[1]
170 comment = fields[2]
171 case keyAlgoECDSA256, keyAlgoECDSA384, keyAlgoECDSA521:
172 panic("unexpected key type")
agl1 2012/11/30 22:36:45 I think a panic is too much. Ideally we would con
173 default:
174 options = strings.Split(string(fields[0]), ",")
agl1 2012/11/30 22:36:45 What if the options contain a space in a quoted va
175 b64key = fields[2]
176 comment = fields[3]
177 }
178 key, err := base64.StdEncoding.DecodeString(b64key)
179 if err != nil {
180 return nil, "", nil, rest, false
181 }
182 out, _, ok = parsePubKey(key)
183
184 return
185 }
186
187 // ParsePublicKey parses an ssh public key formatted for use in
188 // on the wire protocol of SSH.
189 func ParsePublicKey(in []byte) (out interface{}, rest []byte, ok bool) {
190 return parsePubKey(in)
191 }
192
193 // MarshalAuthorizedKey returns a byte stream suitable for inclusion
194 // in an OpenSSH authorized_keys file following the format specified
195 // in the sshd(8) manual page.
196 func MarshalAuthorizedKey(key interface{}) []byte {
197 b := &bytes.Buffer{}
198 switch keyType := key.(type) {
199 case *rsa.PublicKey:
200 b.WriteString(hostAlgoRSA)
201 case *dsa.PublicKey:
202 b.WriteString(hostAlgoDSA)
203 case *OpenSSHCertV01:
204 switch keyType.Key.(type) {
205 case *rsa.PublicKey:
206 b.WriteString(hostAlgoRSACertV01)
207 case *dsa.PublicKey:
208 b.WriteString(hostAlgoDSACertV01)
209 default:
210 panic("unexpected key type")
211 }
212 default:
213 panic("unexpected key type")
214 }
215
216 b.WriteByte(' ')
217 e := base64.NewEncoder(base64.StdEncoding, b)
218 e.Write(serializePublickey(key))
219 e.Close()
220 b.WriteByte('\n')
221 return b.Bytes()
222 }
223
224 // MarshalPublicKey serializes a *rsa.PublicKey, *dsa.PublicKey or
225 // *OpenSSHCertV01 for use on the wire protocol of SSH. It can be
226 // used for comparison with the pubkey argument of ServerConfig's
227 // PublickeyCallback as well as generating an authorized_keys or
228 // host_keys file.
229 func MarshalPublicKey(key interface{}) []byte {
230 return serializePublickey(key)
231 }
OLDNEW
« no previous file with comments | « no previous file | ssh/test/keys_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b