~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/ssh/keys.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012 The Go Authors. All rights reserved.
 
2
// Use of this source code is governed by a BSD-style
 
3
// license that can be found in the LICENSE file.
 
4
 
 
5
package ssh
 
6
 
 
7
import (
 
8
        "bytes"
 
9
        "crypto"
 
10
        "crypto/dsa"
 
11
        "crypto/ecdsa"
 
12
        "crypto/elliptic"
 
13
        "crypto/rsa"
 
14
        "crypto/x509"
 
15
        "encoding/asn1"
 
16
        "encoding/base64"
 
17
        "encoding/pem"
 
18
        "errors"
 
19
        "fmt"
 
20
        "io"
 
21
        "math/big"
 
22
)
 
23
 
 
24
// These constants represent the algorithm names for key types supported by this
 
25
// package.
 
26
const (
 
27
        KeyAlgoRSA      = "ssh-rsa"
 
28
        KeyAlgoDSA      = "ssh-dss"
 
29
        KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
 
30
        KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
 
31
        KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
 
32
)
 
33
 
 
34
// parsePubKey parses a public key of the given algorithm.
 
35
// Use ParsePublicKey for keys with prepended algorithm.
 
36
func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
 
37
        switch algo {
 
38
        case KeyAlgoRSA:
 
39
                return parseRSA(in)
 
40
        case KeyAlgoDSA:
 
41
                return parseDSA(in)
 
42
        case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
 
43
                return parseECDSA(in)
 
44
        case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, 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
}
 
53
 
 
54
// 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
 
56
// removed.
 
57
func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
 
58
        in = bytes.TrimSpace(in)
 
59
 
 
60
        i := bytes.IndexAny(in, " \t")
 
61
        if i == -1 {
 
62
                i = len(in)
 
63
        }
 
64
        base64Key := in[:i]
 
65
 
 
66
        key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
 
67
        n, err := base64.StdEncoding.Decode(key, base64Key)
 
68
        if err != nil {
 
69
                return nil, "", err
 
70
        }
 
71
        key = key[:n]
 
72
        out, err = ParsePublicKey(key)
 
73
        if err != nil {
 
74
                return nil, "", err
 
75
        }
 
76
        comment = string(bytes.TrimSpace(in[i:]))
 
77
        return out, comment, nil
 
78
}
 
79
 
 
80
// ParseAuthorizedKeys parses a public key from an authorized_keys
 
81
// file used in OpenSSH according to the sshd(8) manual page.
 
82
func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
 
83
        for len(in) > 0 {
 
84
                end := bytes.IndexByte(in, '\n')
 
85
                if end != -1 {
 
86
                        rest = in[end+1:]
 
87
                        in = in[:end]
 
88
                } else {
 
89
                        rest = nil
 
90
                }
 
91
 
 
92
                end = bytes.IndexByte(in, '\r')
 
93
                if end != -1 {
 
94
                        in = in[:end]
 
95
                }
 
96
 
 
97
                in = bytes.TrimSpace(in)
 
98
                if len(in) == 0 || in[0] == '#' {
 
99
                        in = rest
 
100
                        continue
 
101
                }
 
102
 
 
103
                i := bytes.IndexAny(in, " \t")
 
104
                if i == -1 {
 
105
                        in = rest
 
106
                        continue
 
107
                }
 
108
 
 
109
                if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
 
110
                        return out, comment, options, rest, nil
 
111
                }
 
112
 
 
113
                // No key type recognised. Maybe there's an options field at
 
114
                // the beginning.
 
115
                var b byte
 
116
                inQuote := false
 
117
                var candidateOptions []string
 
118
                optionStart := 0
 
119
                for i, b = range in {
 
120
                        isEnd := !inQuote && (b == ' ' || b == '\t')
 
121
                        if (b == ',' && !inQuote) || isEnd {
 
122
                                if i-optionStart > 0 {
 
123
                                        candidateOptions = append(candidateOptions, string(in[optionStart:i]))
 
124
                                }
 
125
                                optionStart = i + 1
 
126
                        }
 
127
                        if isEnd {
 
128
                                break
 
129
                        }
 
130
                        if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
 
131
                                inQuote = !inQuote
 
132
                        }
 
133
                }
 
134
                for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
 
135
                        i++
 
136
                }
 
137
                if i == len(in) {
 
138
                        // Invalid line: unmatched quote
 
139
                        in = rest
 
140
                        continue
 
141
                }
 
142
 
 
143
                in = in[i:]
 
144
                i = bytes.IndexAny(in, " \t")
 
145
                if i == -1 {
 
146
                        in = rest
 
147
                        continue
 
148
                }
 
149
 
 
150
                if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
 
151
                        options = candidateOptions
 
152
                        return out, comment, options, rest, nil
 
153
                }
 
154
 
 
155
                in = rest
 
156
                continue
 
157
        }
 
158
 
 
159
        return nil, "", nil, nil, errors.New("ssh: no key found")
 
160
}
 
161
 
 
162
// ParsePublicKey parses an SSH public key formatted for use in
 
163
// the SSH wire protocol according to RFC 4253, section 6.6.
 
164
func ParsePublicKey(in []byte) (out PublicKey, err error) {
 
165
        algo, in, ok := parseString(in)
 
166
        if !ok {
 
167
                return nil, errShortRead
 
168
        }
 
169
        var rest []byte
 
170
        out, rest, err = parsePubKey(in, string(algo))
 
171
        if len(rest) > 0 {
 
172
                return nil, errors.New("ssh: trailing junk in public key")
 
173
        }
 
174
 
 
175
        return out, err
 
176
}
 
177
 
 
178
// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
 
179
// authorized_keys file. The return value ends with newline.
 
180
func MarshalAuthorizedKey(key PublicKey) []byte {
 
181
        b := &bytes.Buffer{}
 
182
        b.WriteString(key.Type())
 
183
        b.WriteByte(' ')
 
184
        e := base64.NewEncoder(base64.StdEncoding, b)
 
185
        e.Write(key.Marshal())
 
186
        e.Close()
 
187
        b.WriteByte('\n')
 
188
        return b.Bytes()
 
189
}
 
190
 
 
191
// PublicKey is an abstraction of different types of public keys.
 
192
type PublicKey interface {
 
193
        // Type returns the key's type, e.g. "ssh-rsa".
 
194
        Type() string
 
195
 
 
196
        // Marshal returns the serialized key data in SSH wire format,
 
197
        // with the name prefix.
 
198
        Marshal() []byte
 
199
 
 
200
        // Verify that sig is a signature on the given data using this
 
201
        // key. This function will hash the data appropriately first.
 
202
        Verify(data []byte, sig *Signature) error
 
203
}
 
204
 
 
205
// A Signer can create signatures that verify against a public key.
 
206
type Signer interface {
 
207
        // PublicKey returns an associated PublicKey instance.
 
208
        PublicKey() PublicKey
 
209
 
 
210
        // Sign returns raw signature for the given data. This method
 
211
        // will apply the hash specified for the keytype to the data.
 
212
        Sign(rand io.Reader, data []byte) (*Signature, error)
 
213
}
 
214
 
 
215
type rsaPublicKey rsa.PublicKey
 
216
 
 
217
func (r *rsaPublicKey) Type() string {
 
218
        return "ssh-rsa"
 
219
}
 
220
 
 
221
// parseRSA parses an RSA key according to RFC 4253, section 6.6.
 
222
func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
 
223
        var w struct {
 
224
                E    *big.Int
 
225
                N    *big.Int
 
226
                Rest []byte `ssh:"rest"`
 
227
        }
 
228
        if err := Unmarshal(in, &w); err != nil {
 
229
                return nil, nil, err
 
230
        }
 
231
 
 
232
        if w.E.BitLen() > 24 {
 
233
                return nil, nil, errors.New("ssh: exponent too large")
 
234
        }
 
235
        e := w.E.Int64()
 
236
        if e < 3 || e&1 == 0 {
 
237
                return nil, nil, errors.New("ssh: incorrect exponent")
 
238
        }
 
239
 
 
240
        var key rsa.PublicKey
 
241
        key.E = int(e)
 
242
        key.N = w.N
 
243
        return (*rsaPublicKey)(&key), w.Rest, nil
 
244
}
 
245
 
 
246
func (r *rsaPublicKey) Marshal() []byte {
 
247
        e := new(big.Int).SetInt64(int64(r.E))
 
248
        wirekey := struct {
 
249
                Name string
 
250
                E    *big.Int
 
251
                N    *big.Int
 
252
        }{
 
253
                KeyAlgoRSA,
 
254
                e,
 
255
                r.N,
 
256
        }
 
257
        return Marshal(&wirekey)
 
258
}
 
259
 
 
260
func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
 
261
        if sig.Format != r.Type() {
 
262
                return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
 
263
        }
 
264
        h := crypto.SHA1.New()
 
265
        h.Write(data)
 
266
        digest := h.Sum(nil)
 
267
        return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob)
 
268
}
 
269
 
 
270
type rsaPrivateKey struct {
 
271
        *rsa.PrivateKey
 
272
}
 
273
 
 
274
func (r *rsaPrivateKey) PublicKey() PublicKey {
 
275
        return (*rsaPublicKey)(&r.PrivateKey.PublicKey)
 
276
}
 
277
 
 
278
func (r *rsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
 
279
        h := crypto.SHA1.New()
 
280
        h.Write(data)
 
281
        digest := h.Sum(nil)
 
282
        blob, err := rsa.SignPKCS1v15(rand, r.PrivateKey, crypto.SHA1, digest)
 
283
        if err != nil {
 
284
                return nil, err
 
285
        }
 
286
        return &Signature{
 
287
                Format: r.PublicKey().Type(),
 
288
                Blob:   blob,
 
289
        }, nil
 
290
}
 
291
 
 
292
type dsaPublicKey dsa.PublicKey
 
293
 
 
294
func (r *dsaPublicKey) Type() string {
 
295
        return "ssh-dss"
 
296
}
 
297
 
 
298
// parseDSA parses an DSA key according to RFC 4253, section 6.6.
 
299
func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
 
300
        var w struct {
 
301
                P, Q, G, Y *big.Int
 
302
                Rest       []byte `ssh:"rest"`
 
303
        }
 
304
        if err := Unmarshal(in, &w); err != nil {
 
305
                return nil, nil, err
 
306
        }
 
307
 
 
308
        key := &dsaPublicKey{
 
309
                Parameters: dsa.Parameters{
 
310
                        P: w.P,
 
311
                        Q: w.Q,
 
312
                        G: w.G,
 
313
                },
 
314
                Y: w.Y,
 
315
        }
 
316
        return key, w.Rest, nil
 
317
}
 
318
 
 
319
func (k *dsaPublicKey) Marshal() []byte {
 
320
        w := struct {
 
321
                Name       string
 
322
                P, Q, G, Y *big.Int
 
323
        }{
 
324
                k.Type(),
 
325
                k.P,
 
326
                k.Q,
 
327
                k.G,
 
328
                k.Y,
 
329
        }
 
330
 
 
331
        return Marshal(&w)
 
332
}
 
333
 
 
334
func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
 
335
        if sig.Format != k.Type() {
 
336
                return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 
337
        }
 
338
        h := crypto.SHA1.New()
 
339
        h.Write(data)
 
340
        digest := h.Sum(nil)
 
341
 
 
342
        // Per RFC 4253, section 6.6,
 
343
        // The value for 'dss_signature_blob' is encoded as a string containing
 
344
        // r, followed by s (which are 160-bit integers, without lengths or
 
345
        // padding, unsigned, and in network byte order).
 
346
        // For DSS purposes, sig.Blob should be exactly 40 bytes in length.
 
347
        if len(sig.Blob) != 40 {
 
348
                return errors.New("ssh: DSA signature parse error")
 
349
        }
 
350
        r := new(big.Int).SetBytes(sig.Blob[:20])
 
351
        s := new(big.Int).SetBytes(sig.Blob[20:])
 
352
        if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
 
353
                return nil
 
354
        }
 
355
        return errors.New("ssh: signature did not verify")
 
356
}
 
357
 
 
358
type dsaPrivateKey struct {
 
359
        *dsa.PrivateKey
 
360
}
 
361
 
 
362
func (k *dsaPrivateKey) PublicKey() PublicKey {
 
363
        return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
 
364
}
 
365
 
 
366
func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
 
367
        h := crypto.SHA1.New()
 
368
        h.Write(data)
 
369
        digest := h.Sum(nil)
 
370
        r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
 
371
        if err != nil {
 
372
                return nil, err
 
373
        }
 
374
 
 
375
        sig := make([]byte, 40)
 
376
        rb := r.Bytes()
 
377
        sb := s.Bytes()
 
378
 
 
379
        copy(sig[20-len(rb):20], rb)
 
380
        copy(sig[40-len(sb):], sb)
 
381
 
 
382
        return &Signature{
 
383
                Format: k.PublicKey().Type(),
 
384
                Blob:   sig,
 
385
        }, nil
 
386
}
 
387
 
 
388
type ecdsaPublicKey ecdsa.PublicKey
 
389
 
 
390
func (key *ecdsaPublicKey) Type() string {
 
391
        return "ecdsa-sha2-" + key.nistID()
 
392
}
 
393
 
 
394
func (key *ecdsaPublicKey) nistID() string {
 
395
        switch key.Params().BitSize {
 
396
        case 256:
 
397
                return "nistp256"
 
398
        case 384:
 
399
                return "nistp384"
 
400
        case 521:
 
401
                return "nistp521"
 
402
        }
 
403
        panic("ssh: unsupported ecdsa key size")
 
404
}
 
405
 
 
406
func supportedEllipticCurve(curve elliptic.Curve) bool {
 
407
        return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
 
408
}
 
409
 
 
410
// ecHash returns the hash to match the given elliptic curve, see RFC
 
411
// 5656, section 6.2.1
 
412
func ecHash(curve elliptic.Curve) crypto.Hash {
 
413
        bitSize := curve.Params().BitSize
 
414
        switch {
 
415
        case bitSize <= 256:
 
416
                return crypto.SHA256
 
417
        case bitSize <= 384:
 
418
                return crypto.SHA384
 
419
        }
 
420
        return crypto.SHA512
 
421
}
 
422
 
 
423
// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
 
424
func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
 
425
        var w struct {
 
426
                Curve    string
 
427
                KeyBytes []byte
 
428
                Rest     []byte `ssh:"rest"`
 
429
        }
 
430
 
 
431
        if err := Unmarshal(in, &w); err != nil {
 
432
                return nil, nil, err
 
433
        }
 
434
 
 
435
        key := new(ecdsa.PublicKey)
 
436
 
 
437
        switch w.Curve {
 
438
        case "nistp256":
 
439
                key.Curve = elliptic.P256()
 
440
        case "nistp384":
 
441
                key.Curve = elliptic.P384()
 
442
        case "nistp521":
 
443
                key.Curve = elliptic.P521()
 
444
        default:
 
445
                return nil, nil, errors.New("ssh: unsupported curve")
 
446
        }
 
447
 
 
448
        key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
 
449
        if key.X == nil || key.Y == nil {
 
450
                return nil, nil, errors.New("ssh: invalid curve point")
 
451
        }
 
452
        return (*ecdsaPublicKey)(key), w.Rest, nil
 
453
}
 
454
 
 
455
func (key *ecdsaPublicKey) Marshal() []byte {
 
456
        // See RFC 5656, section 3.1.
 
457
        keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y)
 
458
        w := struct {
 
459
                Name string
 
460
                ID   string
 
461
                Key  []byte
 
462
        }{
 
463
                key.Type(),
 
464
                key.nistID(),
 
465
                keyBytes,
 
466
        }
 
467
 
 
468
        return Marshal(&w)
 
469
}
 
470
 
 
471
func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
 
472
        if sig.Format != key.Type() {
 
473
                return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
 
474
        }
 
475
 
 
476
        h := ecHash(key.Curve).New()
 
477
        h.Write(data)
 
478
        digest := h.Sum(nil)
 
479
 
 
480
        // Per RFC 5656, section 3.1.2,
 
481
        // The ecdsa_signature_blob value has the following specific encoding:
 
482
        //    mpint    r
 
483
        //    mpint    s
 
484
        var ecSig struct {
 
485
                R *big.Int
 
486
                S *big.Int
 
487
        }
 
488
 
 
489
        if err := Unmarshal(sig.Blob, &ecSig); err != nil {
 
490
                return err
 
491
        }
 
492
 
 
493
        if ecdsa.Verify((*ecdsa.PublicKey)(key), digest, ecSig.R, ecSig.S) {
 
494
                return nil
 
495
        }
 
496
        return errors.New("ssh: signature did not verify")
 
497
}
 
498
 
 
499
type ecdsaPrivateKey struct {
 
500
        *ecdsa.PrivateKey
 
501
}
 
502
 
 
503
func (k *ecdsaPrivateKey) PublicKey() PublicKey {
 
504
        return (*ecdsaPublicKey)(&k.PrivateKey.PublicKey)
 
505
}
 
506
 
 
507
func (k *ecdsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
 
508
        h := ecHash(k.PrivateKey.PublicKey.Curve).New()
 
509
        h.Write(data)
 
510
        digest := h.Sum(nil)
 
511
        r, s, err := ecdsa.Sign(rand, k.PrivateKey, digest)
 
512
        if err != nil {
 
513
                return nil, err
 
514
        }
 
515
 
 
516
        sig := make([]byte, intLength(r)+intLength(s))
 
517
        rest := marshalInt(sig, r)
 
518
        marshalInt(rest, s)
 
519
        return &Signature{
 
520
                Format: k.PublicKey().Type(),
 
521
                Blob:   sig,
 
522
        }, nil
 
523
}
 
524
 
 
525
// NewSignerFromKey takes a pointer to rsa, dsa or ecdsa PrivateKey
 
526
// returns a corresponding Signer instance. EC keys should use P256,
 
527
// P384 or P521.
 
528
func NewSignerFromKey(k interface{}) (Signer, error) {
 
529
        var sshKey Signer
 
530
        switch t := k.(type) {
 
531
        case *rsa.PrivateKey:
 
532
                sshKey = &rsaPrivateKey{t}
 
533
        case *dsa.PrivateKey:
 
534
                sshKey = &dsaPrivateKey{t}
 
535
        case *ecdsa.PrivateKey:
 
536
                if !supportedEllipticCurve(t.Curve) {
 
537
                        return nil, errors.New("ssh: only P256, P384 and P521 EC keys are supported.")
 
538
                }
 
539
 
 
540
                sshKey = &ecdsaPrivateKey{t}
 
541
        default:
 
542
                return nil, fmt.Errorf("ssh: unsupported key type %T", k)
 
543
        }
 
544
        return sshKey, nil
 
545
}
 
546
 
 
547
// NewPublicKey takes a pointer to rsa, dsa or ecdsa PublicKey
 
548
// and returns a corresponding ssh PublicKey instance. EC keys should use P256, P384 or P521.
 
549
func NewPublicKey(k interface{}) (PublicKey, error) {
 
550
        var sshKey PublicKey
 
551
        switch t := k.(type) {
 
552
        case *rsa.PublicKey:
 
553
                sshKey = (*rsaPublicKey)(t)
 
554
        case *ecdsa.PublicKey:
 
555
                if !supportedEllipticCurve(t.Curve) {
 
556
                        return nil, errors.New("ssh: only P256, P384 and P521 EC keys are supported.")
 
557
                }
 
558
                sshKey = (*ecdsaPublicKey)(t)
 
559
        case *dsa.PublicKey:
 
560
                sshKey = (*dsaPublicKey)(t)
 
561
        default:
 
562
                return nil, fmt.Errorf("ssh: unsupported key type %T", k)
 
563
        }
 
564
        return sshKey, nil
 
565
}
 
566
 
 
567
// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
 
568
// the same keys as ParseRawPrivateKey.
 
569
func ParsePrivateKey(pemBytes []byte) (Signer, error) {
 
570
        key, err := ParseRawPrivateKey(pemBytes)
 
571
        if err != nil {
 
572
                return nil, err
 
573
        }
 
574
 
 
575
        return NewSignerFromKey(key)
 
576
}
 
577
 
 
578
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
 
579
// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
 
580
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
 
581
        block, _ := pem.Decode(pemBytes)
 
582
        if block == nil {
 
583
                return nil, errors.New("ssh: no key found")
 
584
        }
 
585
 
 
586
        switch block.Type {
 
587
        case "RSA PRIVATE KEY":
 
588
                return x509.ParsePKCS1PrivateKey(block.Bytes)
 
589
        case "EC PRIVATE KEY":
 
590
                return x509.ParseECPrivateKey(block.Bytes)
 
591
        case "DSA PRIVATE KEY":
 
592
                return ParseDSAPrivateKey(block.Bytes)
 
593
        default:
 
594
                return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
 
595
        }
 
596
}
 
597
 
 
598
// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
 
599
// specified by the OpenSSL DSA man page.
 
600
func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
 
601
        var k struct {
 
602
                Version int
 
603
                P       *big.Int
 
604
                Q       *big.Int
 
605
                G       *big.Int
 
606
                Priv    *big.Int
 
607
                Pub     *big.Int
 
608
        }
 
609
        rest, err := asn1.Unmarshal(der, &k)
 
610
        if err != nil {
 
611
                return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
 
612
        }
 
613
        if len(rest) > 0 {
 
614
                return nil, errors.New("ssh: garbage after DSA key")
 
615
        }
 
616
 
 
617
        return &dsa.PrivateKey{
 
618
                PublicKey: dsa.PublicKey{
 
619
                        Parameters: dsa.Parameters{
 
620
                                P: k.P,
 
621
                                Q: k.Q,
 
622
                                G: k.G,
 
623
                        },
 
624
                        Y: k.Priv,
 
625
                },
 
626
                X: k.Pub,
 
627
        }, nil
 
628
}