1
2
3
4
5 package ssh
6
7 import (
8 "bytes"
9 "crypto"
10 "crypto/aes"
11 "crypto/cipher"
12 "crypto/dsa"
13 "crypto/ecdsa"
14 "crypto/ed25519"
15 "crypto/elliptic"
16 "crypto/md5"
17 "crypto/rand"
18 "crypto/rsa"
19 "crypto/sha256"
20 "crypto/x509"
21 "encoding/asn1"
22 "encoding/base64"
23 "encoding/binary"
24 "encoding/hex"
25 "encoding/pem"
26 "errors"
27 "fmt"
28 "io"
29 "math/big"
30 "strings"
31
32 "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
33 )
34
35
36
37
38 const (
39 KeyAlgoRSA = "ssh-rsa"
40 KeyAlgoDSA = "ssh-dss"
41 KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
42 KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com"
43 KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
44 KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
45 KeyAlgoED25519 = "ssh-ed25519"
46 KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com"
47
48
49
50
51 KeyAlgoRSASHA256 = "rsa-sha2-256"
52 KeyAlgoRSASHA512 = "rsa-sha2-512"
53 )
54
55 const (
56
57 SigAlgoRSA = KeyAlgoRSA
58
59 SigAlgoRSASHA2256 = KeyAlgoRSASHA256
60
61 SigAlgoRSASHA2512 = KeyAlgoRSASHA512
62 )
63
64
65
66 func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
67 switch algo {
68 case KeyAlgoRSA:
69 return parseRSA(in)
70 case KeyAlgoDSA:
71 return parseDSA(in)
72 case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
73 return parseECDSA(in)
74 case KeyAlgoSKECDSA256:
75 return parseSKECDSA(in)
76 case KeyAlgoED25519:
77 return parseED25519(in)
78 case KeyAlgoSKED25519:
79 return parseSKEd25519(in)
80 case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
81 cert, err := parseCert(in, certKeyAlgoNames[algo])
82 if err != nil {
83 return nil, nil, err
84 }
85 return cert, nil, nil
86 }
87 return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
88 }
89
90
91
92
93 func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
94 in = bytes.TrimSpace(in)
95
96 i := bytes.IndexAny(in, " \t")
97 if i == -1 {
98 i = len(in)
99 }
100 base64Key := in[:i]
101
102 key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
103 n, err := base64.StdEncoding.Decode(key, base64Key)
104 if err != nil {
105 return nil, "", err
106 }
107 key = key[:n]
108 out, err = ParsePublicKey(key)
109 if err != nil {
110 return nil, "", err
111 }
112 comment = string(bytes.TrimSpace(in[i:]))
113 return out, comment, nil
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {
132 for len(in) > 0 {
133 end := bytes.IndexByte(in, '\n')
134 if end != -1 {
135 rest = in[end+1:]
136 in = in[:end]
137 } else {
138 rest = nil
139 }
140
141 end = bytes.IndexByte(in, '\r')
142 if end != -1 {
143 in = in[:end]
144 }
145
146 in = bytes.TrimSpace(in)
147 if len(in) == 0 || in[0] == '#' {
148 in = rest
149 continue
150 }
151
152 i := bytes.IndexAny(in, " \t")
153 if i == -1 {
154 in = rest
155 continue
156 }
157
158
159
160 keyFields := bytes.Fields(in)
161 if len(keyFields) < 3 || len(keyFields) > 5 {
162 return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data")
163 }
164
165
166
167 marker := ""
168 if keyFields[0][0] == '@' {
169 marker = string(keyFields[0][1:])
170 keyFields = keyFields[1:]
171 }
172
173 hosts := string(keyFields[0])
174
175
176
177
178 key := bytes.Join(keyFields[2:], []byte(" "))
179 if pubKey, comment, err = parseAuthorizedKey(key); err != nil {
180 return "", nil, nil, "", nil, err
181 }
182
183 return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil
184 }
185
186 return "", nil, nil, "", nil, io.EOF
187 }
188
189
190
191 func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
192 for len(in) > 0 {
193 end := bytes.IndexByte(in, '\n')
194 if end != -1 {
195 rest = in[end+1:]
196 in = in[:end]
197 } else {
198 rest = nil
199 }
200
201 end = bytes.IndexByte(in, '\r')
202 if end != -1 {
203 in = in[:end]
204 }
205
206 in = bytes.TrimSpace(in)
207 if len(in) == 0 || in[0] == '#' {
208 in = rest
209 continue
210 }
211
212 i := bytes.IndexAny(in, " \t")
213 if i == -1 {
214 in = rest
215 continue
216 }
217
218 if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
219 return out, comment, options, rest, nil
220 }
221
222
223
224 var b byte
225 inQuote := false
226 var candidateOptions []string
227 optionStart := 0
228 for i, b = range in {
229 isEnd := !inQuote && (b == ' ' || b == '\t')
230 if (b == ',' && !inQuote) || isEnd {
231 if i-optionStart > 0 {
232 candidateOptions = append(candidateOptions, string(in[optionStart:i]))
233 }
234 optionStart = i + 1
235 }
236 if isEnd {
237 break
238 }
239 if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
240 inQuote = !inQuote
241 }
242 }
243 for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
244 i++
245 }
246 if i == len(in) {
247
248 in = rest
249 continue
250 }
251
252 in = in[i:]
253 i = bytes.IndexAny(in, " \t")
254 if i == -1 {
255 in = rest
256 continue
257 }
258
259 if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
260 options = candidateOptions
261 return out, comment, options, rest, nil
262 }
263
264 in = rest
265 continue
266 }
267
268 return nil, "", nil, nil, errors.New("ssh: no key found")
269 }
270
271
272
273 func ParsePublicKey(in []byte) (out PublicKey, err error) {
274 algo, in, ok := parseString(in)
275 if !ok {
276 return nil, errShortRead
277 }
278 var rest []byte
279 out, rest, err = parsePubKey(in, string(algo))
280 if len(rest) > 0 {
281 return nil, errors.New("ssh: trailing junk in public key")
282 }
283
284 return out, err
285 }
286
287
288
289 func MarshalAuthorizedKey(key PublicKey) []byte {
290 b := &bytes.Buffer{}
291 b.WriteString(key.Type())
292 b.WriteByte(' ')
293 e := base64.NewEncoder(base64.StdEncoding, b)
294 e.Write(key.Marshal())
295 e.Close()
296 b.WriteByte('\n')
297 return b.Bytes()
298 }
299
300
301
302 func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) {
303 return marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler)
304 }
305
306
307
308 func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) {
309 return marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase))
310 }
311
312
313
314
315 type PublicKey interface {
316
317 Type() string
318
319
320
321 Marshal() []byte
322
323
324
325
326
327 Verify(data []byte, sig *Signature) error
328 }
329
330
331
332 type CryptoPublicKey interface {
333 CryptoPublicKey() crypto.PublicKey
334 }
335
336
337
338
339 type Signer interface {
340
341 PublicKey() PublicKey
342
343
344
345
346
347 Sign(rand io.Reader, data []byte) (*Signature, error)
348 }
349
350
351
352
353
354
355
356 type AlgorithmSigner interface {
357 Signer
358
359
360
361
362
363 SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
364 }
365
366
367
368 type MultiAlgorithmSigner interface {
369 AlgorithmSigner
370
371
372
373 Algorithms() []string
374 }
375
376
377
378
379
380 func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) {
381 if len(algorithms) == 0 {
382 return nil, errors.New("ssh: please specify at least one valid signing algorithm")
383 }
384 var signerAlgos []string
385 supportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type()))
386 if s, ok := signer.(*multiAlgorithmSigner); ok {
387 signerAlgos = s.Algorithms()
388 } else {
389 signerAlgos = supportedAlgos
390 }
391
392 for _, algo := range algorithms {
393 if !contains(supportedAlgos, algo) {
394 return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q",
395 algo, signer.PublicKey().Type())
396 }
397 if !contains(signerAlgos, algo) {
398 return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo)
399 }
400 }
401 return &multiAlgorithmSigner{
402 AlgorithmSigner: signer,
403 supportedAlgorithms: algorithms,
404 }, nil
405 }
406
407 type multiAlgorithmSigner struct {
408 AlgorithmSigner
409 supportedAlgorithms []string
410 }
411
412 func (s *multiAlgorithmSigner) Algorithms() []string {
413 return s.supportedAlgorithms
414 }
415
416 func (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool {
417 if algorithm == "" {
418 algorithm = underlyingAlgo(s.PublicKey().Type())
419 }
420 for _, algo := range s.supportedAlgorithms {
421 if algorithm == algo {
422 return true
423 }
424 }
425 return false
426 }
427
428 func (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
429 if !s.isAlgorithmSupported(algorithm) {
430 return nil, fmt.Errorf("ssh: algorithm %q is not supported: %v", algorithm, s.supportedAlgorithms)
431 }
432 return s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
433 }
434
435 type rsaPublicKey rsa.PublicKey
436
437 func (r *rsaPublicKey) Type() string {
438 return "ssh-rsa"
439 }
440
441
442 func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
443 var w struct {
444 E *big.Int
445 N *big.Int
446 Rest []byte `ssh:"rest"`
447 }
448 if err := Unmarshal(in, &w); err != nil {
449 return nil, nil, err
450 }
451
452 if w.E.BitLen() > 24 {
453 return nil, nil, errors.New("ssh: exponent too large")
454 }
455 e := w.E.Int64()
456 if e < 3 || e&1 == 0 {
457 return nil, nil, errors.New("ssh: incorrect exponent")
458 }
459
460 var key rsa.PublicKey
461 key.E = int(e)
462 key.N = w.N
463 return (*rsaPublicKey)(&key), w.Rest, nil
464 }
465
466 func (r *rsaPublicKey) Marshal() []byte {
467 e := new(big.Int).SetInt64(int64(r.E))
468
469
470 wirekey := struct {
471 Name string
472 E *big.Int
473 N *big.Int
474 }{
475 KeyAlgoRSA,
476 e,
477 r.N,
478 }
479 return Marshal(&wirekey)
480 }
481
482 func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
483 supportedAlgos := algorithmsForKeyFormat(r.Type())
484 if !contains(supportedAlgos, sig.Format) {
485 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
486 }
487 hash := hashFuncs[sig.Format]
488 h := hash.New()
489 h.Write(data)
490 digest := h.Sum(nil)
491 return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, sig.Blob)
492 }
493
494 func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
495 return (*rsa.PublicKey)(r)
496 }
497
498 type dsaPublicKey dsa.PublicKey
499
500 func (k *dsaPublicKey) Type() string {
501 return "ssh-dss"
502 }
503
504 func checkDSAParams(param *dsa.Parameters) error {
505
506
507
508 if l := param.P.BitLen(); l != 1024 {
509 return fmt.Errorf("ssh: unsupported DSA key size %d", l)
510 }
511
512 return nil
513 }
514
515
516 func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
517 var w struct {
518 P, Q, G, Y *big.Int
519 Rest []byte `ssh:"rest"`
520 }
521 if err := Unmarshal(in, &w); err != nil {
522 return nil, nil, err
523 }
524
525 param := dsa.Parameters{
526 P: w.P,
527 Q: w.Q,
528 G: w.G,
529 }
530 if err := checkDSAParams(¶m); err != nil {
531 return nil, nil, err
532 }
533
534 key := &dsaPublicKey{
535 Parameters: param,
536 Y: w.Y,
537 }
538 return key, w.Rest, nil
539 }
540
541 func (k *dsaPublicKey) Marshal() []byte {
542
543
544 w := struct {
545 Name string
546 P, Q, G, Y *big.Int
547 }{
548 k.Type(),
549 k.P,
550 k.Q,
551 k.G,
552 k.Y,
553 }
554
555 return Marshal(&w)
556 }
557
558 func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
559 if sig.Format != k.Type() {
560 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
561 }
562 h := hashFuncs[sig.Format].New()
563 h.Write(data)
564 digest := h.Sum(nil)
565
566
567
568
569
570
571 if len(sig.Blob) != 40 {
572 return errors.New("ssh: DSA signature parse error")
573 }
574 r := new(big.Int).SetBytes(sig.Blob[:20])
575 s := new(big.Int).SetBytes(sig.Blob[20:])
576 if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
577 return nil
578 }
579 return errors.New("ssh: signature did not verify")
580 }
581
582 func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
583 return (*dsa.PublicKey)(k)
584 }
585
586 type dsaPrivateKey struct {
587 *dsa.PrivateKey
588 }
589
590 func (k *dsaPrivateKey) PublicKey() PublicKey {
591 return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
592 }
593
594 func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
595 return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
596 }
597
598 func (k *dsaPrivateKey) Algorithms() []string {
599 return []string{k.PublicKey().Type()}
600 }
601
602 func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
603 if algorithm != "" && algorithm != k.PublicKey().Type() {
604 return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
605 }
606
607 h := hashFuncs[k.PublicKey().Type()].New()
608 h.Write(data)
609 digest := h.Sum(nil)
610 r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
611 if err != nil {
612 return nil, err
613 }
614
615 sig := make([]byte, 40)
616 rb := r.Bytes()
617 sb := s.Bytes()
618
619 copy(sig[20-len(rb):20], rb)
620 copy(sig[40-len(sb):], sb)
621
622 return &Signature{
623 Format: k.PublicKey().Type(),
624 Blob: sig,
625 }, nil
626 }
627
628 type ecdsaPublicKey ecdsa.PublicKey
629
630 func (k *ecdsaPublicKey) Type() string {
631 return "ecdsa-sha2-" + k.nistID()
632 }
633
634 func (k *ecdsaPublicKey) nistID() string {
635 switch k.Params().BitSize {
636 case 256:
637 return "nistp256"
638 case 384:
639 return "nistp384"
640 case 521:
641 return "nistp521"
642 }
643 panic("ssh: unsupported ecdsa key size")
644 }
645
646 type ed25519PublicKey ed25519.PublicKey
647
648 func (k ed25519PublicKey) Type() string {
649 return KeyAlgoED25519
650 }
651
652 func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
653 var w struct {
654 KeyBytes []byte
655 Rest []byte `ssh:"rest"`
656 }
657
658 if err := Unmarshal(in, &w); err != nil {
659 return nil, nil, err
660 }
661
662 if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
663 return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
664 }
665
666 return ed25519PublicKey(w.KeyBytes), w.Rest, nil
667 }
668
669 func (k ed25519PublicKey) Marshal() []byte {
670 w := struct {
671 Name string
672 KeyBytes []byte
673 }{
674 KeyAlgoED25519,
675 []byte(k),
676 }
677 return Marshal(&w)
678 }
679
680 func (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {
681 if sig.Format != k.Type() {
682 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
683 }
684 if l := len(k); l != ed25519.PublicKeySize {
685 return fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
686 }
687
688 if ok := ed25519.Verify(ed25519.PublicKey(k), b, sig.Blob); !ok {
689 return errors.New("ssh: signature did not verify")
690 }
691
692 return nil
693 }
694
695 func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
696 return ed25519.PublicKey(k)
697 }
698
699 func supportedEllipticCurve(curve elliptic.Curve) bool {
700 return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
701 }
702
703
704 func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
705 var w struct {
706 Curve string
707 KeyBytes []byte
708 Rest []byte `ssh:"rest"`
709 }
710
711 if err := Unmarshal(in, &w); err != nil {
712 return nil, nil, err
713 }
714
715 key := new(ecdsa.PublicKey)
716
717 switch w.Curve {
718 case "nistp256":
719 key.Curve = elliptic.P256()
720 case "nistp384":
721 key.Curve = elliptic.P384()
722 case "nistp521":
723 key.Curve = elliptic.P521()
724 default:
725 return nil, nil, errors.New("ssh: unsupported curve")
726 }
727
728 key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
729 if key.X == nil || key.Y == nil {
730 return nil, nil, errors.New("ssh: invalid curve point")
731 }
732 return (*ecdsaPublicKey)(key), w.Rest, nil
733 }
734
735 func (k *ecdsaPublicKey) Marshal() []byte {
736
737 keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
738
739
740 w := struct {
741 Name string
742 ID string
743 Key []byte
744 }{
745 k.Type(),
746 k.nistID(),
747 keyBytes,
748 }
749
750 return Marshal(&w)
751 }
752
753 func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
754 if sig.Format != k.Type() {
755 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
756 }
757
758 h := hashFuncs[sig.Format].New()
759 h.Write(data)
760 digest := h.Sum(nil)
761
762
763
764
765
766 var ecSig struct {
767 R *big.Int
768 S *big.Int
769 }
770
771 if err := Unmarshal(sig.Blob, &ecSig); err != nil {
772 return err
773 }
774
775 if ecdsa.Verify((*ecdsa.PublicKey)(k), digest, ecSig.R, ecSig.S) {
776 return nil
777 }
778 return errors.New("ssh: signature did not verify")
779 }
780
781 func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
782 return (*ecdsa.PublicKey)(k)
783 }
784
785
786
787 type skFields struct {
788
789 Flags byte
790
791
792
793 Counter uint32
794 }
795
796 type skECDSAPublicKey struct {
797
798
799 application string
800 ecdsa.PublicKey
801 }
802
803 func (k *skECDSAPublicKey) Type() string {
804 return KeyAlgoSKECDSA256
805 }
806
807 func (k *skECDSAPublicKey) nistID() string {
808 return "nistp256"
809 }
810
811 func parseSKECDSA(in []byte) (out PublicKey, rest []byte, err error) {
812 var w struct {
813 Curve string
814 KeyBytes []byte
815 Application string
816 Rest []byte `ssh:"rest"`
817 }
818
819 if err := Unmarshal(in, &w); err != nil {
820 return nil, nil, err
821 }
822
823 key := new(skECDSAPublicKey)
824 key.application = w.Application
825
826 if w.Curve != "nistp256" {
827 return nil, nil, errors.New("ssh: unsupported curve")
828 }
829 key.Curve = elliptic.P256()
830
831 key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
832 if key.X == nil || key.Y == nil {
833 return nil, nil, errors.New("ssh: invalid curve point")
834 }
835
836 return key, w.Rest, nil
837 }
838
839 func (k *skECDSAPublicKey) Marshal() []byte {
840
841 keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
842 w := struct {
843 Name string
844 ID string
845 Key []byte
846 Application string
847 }{
848 k.Type(),
849 k.nistID(),
850 keyBytes,
851 k.application,
852 }
853
854 return Marshal(&w)
855 }
856
857 func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
858 if sig.Format != k.Type() {
859 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
860 }
861
862 h := hashFuncs[sig.Format].New()
863 h.Write([]byte(k.application))
864 appDigest := h.Sum(nil)
865
866 h.Reset()
867 h.Write(data)
868 dataDigest := h.Sum(nil)
869
870 var ecSig struct {
871 R *big.Int
872 S *big.Int
873 }
874 if err := Unmarshal(sig.Blob, &ecSig); err != nil {
875 return err
876 }
877
878 var skf skFields
879 if err := Unmarshal(sig.Rest, &skf); err != nil {
880 return err
881 }
882
883 blob := struct {
884 ApplicationDigest []byte `ssh:"rest"`
885 Flags byte
886 Counter uint32
887 MessageDigest []byte `ssh:"rest"`
888 }{
889 appDigest,
890 skf.Flags,
891 skf.Counter,
892 dataDigest,
893 }
894
895 original := Marshal(blob)
896
897 h.Reset()
898 h.Write(original)
899 digest := h.Sum(nil)
900
901 if ecdsa.Verify((*ecdsa.PublicKey)(&k.PublicKey), digest, ecSig.R, ecSig.S) {
902 return nil
903 }
904 return errors.New("ssh: signature did not verify")
905 }
906
907 type skEd25519PublicKey struct {
908
909
910 application string
911 ed25519.PublicKey
912 }
913
914 func (k *skEd25519PublicKey) Type() string {
915 return KeyAlgoSKED25519
916 }
917
918 func parseSKEd25519(in []byte) (out PublicKey, rest []byte, err error) {
919 var w struct {
920 KeyBytes []byte
921 Application string
922 Rest []byte `ssh:"rest"`
923 }
924
925 if err := Unmarshal(in, &w); err != nil {
926 return nil, nil, err
927 }
928
929 if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
930 return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
931 }
932
933 key := new(skEd25519PublicKey)
934 key.application = w.Application
935 key.PublicKey = ed25519.PublicKey(w.KeyBytes)
936
937 return key, w.Rest, nil
938 }
939
940 func (k *skEd25519PublicKey) Marshal() []byte {
941 w := struct {
942 Name string
943 KeyBytes []byte
944 Application string
945 }{
946 KeyAlgoSKED25519,
947 []byte(k.PublicKey),
948 k.application,
949 }
950 return Marshal(&w)
951 }
952
953 func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
954 if sig.Format != k.Type() {
955 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
956 }
957 if l := len(k.PublicKey); l != ed25519.PublicKeySize {
958 return fmt.Errorf("invalid size %d for Ed25519 public key", l)
959 }
960
961 h := hashFuncs[sig.Format].New()
962 h.Write([]byte(k.application))
963 appDigest := h.Sum(nil)
964
965 h.Reset()
966 h.Write(data)
967 dataDigest := h.Sum(nil)
968
969 var edSig struct {
970 Signature []byte `ssh:"rest"`
971 }
972
973 if err := Unmarshal(sig.Blob, &edSig); err != nil {
974 return err
975 }
976
977 var skf skFields
978 if err := Unmarshal(sig.Rest, &skf); err != nil {
979 return err
980 }
981
982 blob := struct {
983 ApplicationDigest []byte `ssh:"rest"`
984 Flags byte
985 Counter uint32
986 MessageDigest []byte `ssh:"rest"`
987 }{
988 appDigest,
989 skf.Flags,
990 skf.Counter,
991 dataDigest,
992 }
993
994 original := Marshal(blob)
995
996 if ok := ed25519.Verify(k.PublicKey, original, edSig.Signature); !ok {
997 return errors.New("ssh: signature did not verify")
998 }
999
1000 return nil
1001 }
1002
1003
1004
1005
1006
1007 func NewSignerFromKey(key interface{}) (Signer, error) {
1008 switch key := key.(type) {
1009 case crypto.Signer:
1010 return NewSignerFromSigner(key)
1011 case *dsa.PrivateKey:
1012 return newDSAPrivateKey(key)
1013 default:
1014 return nil, fmt.Errorf("ssh: unsupported key type %T", key)
1015 }
1016 }
1017
1018 func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
1019 if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
1020 return nil, err
1021 }
1022
1023 return &dsaPrivateKey{key}, nil
1024 }
1025
1026 type wrappedSigner struct {
1027 signer crypto.Signer
1028 pubKey PublicKey
1029 }
1030
1031
1032
1033
1034 func NewSignerFromSigner(signer crypto.Signer) (Signer, error) {
1035 pubKey, err := NewPublicKey(signer.Public())
1036 if err != nil {
1037 return nil, err
1038 }
1039
1040 return &wrappedSigner{signer, pubKey}, nil
1041 }
1042
1043 func (s *wrappedSigner) PublicKey() PublicKey {
1044 return s.pubKey
1045 }
1046
1047 func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
1048 return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
1049 }
1050
1051 func (s *wrappedSigner) Algorithms() []string {
1052 return algorithmsForKeyFormat(s.pubKey.Type())
1053 }
1054
1055 func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
1056 if algorithm == "" {
1057 algorithm = s.pubKey.Type()
1058 }
1059
1060 if !contains(s.Algorithms(), algorithm) {
1061 return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
1062 }
1063
1064 hashFunc := hashFuncs[algorithm]
1065 var digest []byte
1066 if hashFunc != 0 {
1067 h := hashFunc.New()
1068 h.Write(data)
1069 digest = h.Sum(nil)
1070 } else {
1071 digest = data
1072 }
1073
1074 signature, err := s.signer.Sign(rand, digest, hashFunc)
1075 if err != nil {
1076 return nil, err
1077 }
1078
1079
1080
1081
1082 switch s.pubKey.(type) {
1083 case *ecdsaPublicKey, *dsaPublicKey:
1084 type asn1Signature struct {
1085 R, S *big.Int
1086 }
1087 asn1Sig := new(asn1Signature)
1088 _, err := asn1.Unmarshal(signature, asn1Sig)
1089 if err != nil {
1090 return nil, err
1091 }
1092
1093 switch s.pubKey.(type) {
1094 case *ecdsaPublicKey:
1095 signature = Marshal(asn1Sig)
1096
1097 case *dsaPublicKey:
1098 signature = make([]byte, 40)
1099 r := asn1Sig.R.Bytes()
1100 s := asn1Sig.S.Bytes()
1101 copy(signature[20-len(r):20], r)
1102 copy(signature[40-len(s):40], s)
1103 }
1104 }
1105
1106 return &Signature{
1107 Format: algorithm,
1108 Blob: signature,
1109 }, nil
1110 }
1111
1112
1113
1114
1115 func NewPublicKey(key interface{}) (PublicKey, error) {
1116 switch key := key.(type) {
1117 case *rsa.PublicKey:
1118 return (*rsaPublicKey)(key), nil
1119 case *ecdsa.PublicKey:
1120 if !supportedEllipticCurve(key.Curve) {
1121 return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported")
1122 }
1123 return (*ecdsaPublicKey)(key), nil
1124 case *dsa.PublicKey:
1125 return (*dsaPublicKey)(key), nil
1126 case ed25519.PublicKey:
1127 if l := len(key); l != ed25519.PublicKeySize {
1128 return nil, fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
1129 }
1130 return ed25519PublicKey(key), nil
1131 default:
1132 return nil, fmt.Errorf("ssh: unsupported key type %T", key)
1133 }
1134 }
1135
1136
1137
1138
1139 func ParsePrivateKey(pemBytes []byte) (Signer, error) {
1140 key, err := ParseRawPrivateKey(pemBytes)
1141 if err != nil {
1142 return nil, err
1143 }
1144
1145 return NewSignerFromKey(key)
1146 }
1147
1148
1149
1150
1151 func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error) {
1152 key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase)
1153 if err != nil {
1154 return nil, err
1155 }
1156
1157 return NewSignerFromKey(key)
1158 }
1159
1160
1161
1162
1163
1164 func encryptedBlock(block *pem.Block) bool {
1165 return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
1166 }
1167
1168
1169
1170 type PassphraseMissingError struct {
1171
1172
1173 PublicKey PublicKey
1174 }
1175
1176 func (*PassphraseMissingError) Error() string {
1177 return "ssh: this private key is passphrase protected"
1178 }
1179
1180
1181
1182
1183 func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
1184 block, _ := pem.Decode(pemBytes)
1185 if block == nil {
1186 return nil, errors.New("ssh: no key found")
1187 }
1188
1189 if encryptedBlock(block) {
1190 return nil, &PassphraseMissingError{}
1191 }
1192
1193 switch block.Type {
1194 case "RSA PRIVATE KEY":
1195 return x509.ParsePKCS1PrivateKey(block.Bytes)
1196
1197 case "PRIVATE KEY":
1198 return x509.ParsePKCS8PrivateKey(block.Bytes)
1199 case "EC PRIVATE KEY":
1200 return x509.ParseECPrivateKey(block.Bytes)
1201 case "DSA PRIVATE KEY":
1202 return ParseDSAPrivateKey(block.Bytes)
1203 case "OPENSSH PRIVATE KEY":
1204 return parseOpenSSHPrivateKey(block.Bytes, unencryptedOpenSSHKey)
1205 default:
1206 return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
1207 }
1208 }
1209
1210
1211
1212
1213 func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error) {
1214 block, _ := pem.Decode(pemBytes)
1215 if block == nil {
1216 return nil, errors.New("ssh: no key found")
1217 }
1218
1219 if block.Type == "OPENSSH PRIVATE KEY" {
1220 return parseOpenSSHPrivateKey(block.Bytes, passphraseProtectedOpenSSHKey(passphrase))
1221 }
1222
1223 if !encryptedBlock(block) || !x509.IsEncryptedPEMBlock(block) {
1224 return nil, errors.New("ssh: not an encrypted key")
1225 }
1226
1227 buf, err := x509.DecryptPEMBlock(block, passphrase)
1228 if err != nil {
1229 if err == x509.IncorrectPasswordError {
1230 return nil, err
1231 }
1232 return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
1233 }
1234
1235 var result interface{}
1236
1237 switch block.Type {
1238 case "RSA PRIVATE KEY":
1239 result, err = x509.ParsePKCS1PrivateKey(buf)
1240 case "EC PRIVATE KEY":
1241 result, err = x509.ParseECPrivateKey(buf)
1242 case "DSA PRIVATE KEY":
1243 result, err = ParseDSAPrivateKey(buf)
1244 default:
1245 err = fmt.Errorf("ssh: unsupported key type %q", block.Type)
1246 }
1247
1248
1249
1250
1251 if _, ok := err.(asn1.StructuralError); ok {
1252 return nil, x509.IncorrectPasswordError
1253 }
1254
1255 return result, err
1256 }
1257
1258
1259
1260 func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
1261 var k struct {
1262 Version int
1263 P *big.Int
1264 Q *big.Int
1265 G *big.Int
1266 Pub *big.Int
1267 Priv *big.Int
1268 }
1269 rest, err := asn1.Unmarshal(der, &k)
1270 if err != nil {
1271 return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
1272 }
1273 if len(rest) > 0 {
1274 return nil, errors.New("ssh: garbage after DSA key")
1275 }
1276
1277 return &dsa.PrivateKey{
1278 PublicKey: dsa.PublicKey{
1279 Parameters: dsa.Parameters{
1280 P: k.P,
1281 Q: k.Q,
1282 G: k.G,
1283 },
1284 Y: k.Pub,
1285 },
1286 X: k.Priv,
1287 }, nil
1288 }
1289
1290 func unencryptedOpenSSHKey(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
1291 if kdfName != "none" || cipherName != "none" {
1292 return nil, &PassphraseMissingError{}
1293 }
1294 if kdfOpts != "" {
1295 return nil, errors.New("ssh: invalid openssh private key")
1296 }
1297 return privKeyBlock, nil
1298 }
1299
1300 func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
1301 return func(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
1302 if kdfName == "none" || cipherName == "none" {
1303 return nil, errors.New("ssh: key is not password protected")
1304 }
1305 if kdfName != "bcrypt" {
1306 return nil, fmt.Errorf("ssh: unknown KDF %q, only supports %q", kdfName, "bcrypt")
1307 }
1308
1309 var opts struct {
1310 Salt string
1311 Rounds uint32
1312 }
1313 if err := Unmarshal([]byte(kdfOpts), &opts); err != nil {
1314 return nil, err
1315 }
1316
1317 k, err := bcrypt_pbkdf.Key(passphrase, []byte(opts.Salt), int(opts.Rounds), 32+16)
1318 if err != nil {
1319 return nil, err
1320 }
1321 key, iv := k[:32], k[32:]
1322
1323 c, err := aes.NewCipher(key)
1324 if err != nil {
1325 return nil, err
1326 }
1327 switch cipherName {
1328 case "aes256-ctr":
1329 ctr := cipher.NewCTR(c, iv)
1330 ctr.XORKeyStream(privKeyBlock, privKeyBlock)
1331 case "aes256-cbc":
1332 if len(privKeyBlock)%c.BlockSize() != 0 {
1333 return nil, fmt.Errorf("ssh: invalid encrypted private key length, not a multiple of the block size")
1334 }
1335 cbc := cipher.NewCBCDecrypter(c, iv)
1336 cbc.CryptBlocks(privKeyBlock, privKeyBlock)
1337 default:
1338 return nil, fmt.Errorf("ssh: unknown cipher %q, only supports %q or %q", cipherName, "aes256-ctr", "aes256-cbc")
1339 }
1340
1341 return privKeyBlock, nil
1342 }
1343 }
1344
1345 func unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) {
1346 key := generateOpenSSHPadding(privKeyBlock, 8)
1347 return key, "none", "none", "", nil
1348 }
1349
1350 func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc {
1351 return func(privKeyBlock []byte) ([]byte, string, string, string, error) {
1352 salt := make([]byte, 16)
1353 if _, err := rand.Read(salt); err != nil {
1354 return nil, "", "", "", err
1355 }
1356
1357 opts := struct {
1358 Salt []byte
1359 Rounds uint32
1360 }{salt, 16}
1361
1362
1363 k, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize)
1364 if err != nil {
1365 return nil, "", "", "", err
1366 }
1367
1368
1369 keyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize)
1370
1371
1372
1373 dst := make([]byte, len(keyBlock))
1374 key, iv := k[:32], k[32:]
1375 block, err := aes.NewCipher(key)
1376 if err != nil {
1377 return nil, "", "", "", err
1378 }
1379
1380 stream := cipher.NewCTR(block, iv)
1381 stream.XORKeyStream(dst, keyBlock)
1382
1383 return dst, "aes256-ctr", "bcrypt", string(Marshal(opts)), nil
1384 }
1385 }
1386
1387 const privateKeyAuthMagic = "openssh-key-v1\x00"
1388
1389 type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
1390 type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error)
1391
1392 type openSSHEncryptedPrivateKey struct {
1393 CipherName string
1394 KdfName string
1395 KdfOpts string
1396 NumKeys uint32
1397 PubKey []byte
1398 PrivKeyBlock []byte
1399 }
1400
1401 type openSSHPrivateKey struct {
1402 Check1 uint32
1403 Check2 uint32
1404 Keytype string
1405 Rest []byte `ssh:"rest"`
1406 }
1407
1408 type openSSHRSAPrivateKey struct {
1409 N *big.Int
1410 E *big.Int
1411 D *big.Int
1412 Iqmp *big.Int
1413 P *big.Int
1414 Q *big.Int
1415 Comment string
1416 Pad []byte `ssh:"rest"`
1417 }
1418
1419 type openSSHEd25519PrivateKey struct {
1420 Pub []byte
1421 Priv []byte
1422 Comment string
1423 Pad []byte `ssh:"rest"`
1424 }
1425
1426 type openSSHECDSAPrivateKey struct {
1427 Curve string
1428 Pub []byte
1429 D *big.Int
1430 Comment string
1431 Pad []byte `ssh:"rest"`
1432 }
1433
1434
1435
1436
1437
1438 func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
1439 if len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic {
1440 return nil, errors.New("ssh: invalid openssh private key format")
1441 }
1442 remaining := key[len(privateKeyAuthMagic):]
1443
1444 var w openSSHEncryptedPrivateKey
1445 if err := Unmarshal(remaining, &w); err != nil {
1446 return nil, err
1447 }
1448 if w.NumKeys != 1 {
1449
1450
1451 return nil, errors.New("ssh: multi-key files are not supported")
1452 }
1453
1454 privKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock)
1455 if err != nil {
1456 if err, ok := err.(*PassphraseMissingError); ok {
1457 pub, errPub := ParsePublicKey(w.PubKey)
1458 if errPub != nil {
1459 return nil, fmt.Errorf("ssh: failed to parse embedded public key: %v", errPub)
1460 }
1461 err.PublicKey = pub
1462 }
1463 return nil, err
1464 }
1465
1466 var pk1 openSSHPrivateKey
1467 if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
1468 if w.CipherName != "none" {
1469 return nil, x509.IncorrectPasswordError
1470 }
1471 return nil, errors.New("ssh: malformed OpenSSH key")
1472 }
1473
1474 switch pk1.Keytype {
1475 case KeyAlgoRSA:
1476 var key openSSHRSAPrivateKey
1477 if err := Unmarshal(pk1.Rest, &key); err != nil {
1478 return nil, err
1479 }
1480
1481 if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
1482 return nil, err
1483 }
1484
1485 pk := &rsa.PrivateKey{
1486 PublicKey: rsa.PublicKey{
1487 N: key.N,
1488 E: int(key.E.Int64()),
1489 },
1490 D: key.D,
1491 Primes: []*big.Int{key.P, key.Q},
1492 }
1493
1494 if err := pk.Validate(); err != nil {
1495 return nil, err
1496 }
1497
1498 pk.Precompute()
1499
1500 return pk, nil
1501 case KeyAlgoED25519:
1502 var key openSSHEd25519PrivateKey
1503 if err := Unmarshal(pk1.Rest, &key); err != nil {
1504 return nil, err
1505 }
1506
1507 if len(key.Priv) != ed25519.PrivateKeySize {
1508 return nil, errors.New("ssh: private key unexpected length")
1509 }
1510
1511 if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
1512 return nil, err
1513 }
1514
1515 pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
1516 copy(pk, key.Priv)
1517 return &pk, nil
1518 case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
1519 var key openSSHECDSAPrivateKey
1520 if err := Unmarshal(pk1.Rest, &key); err != nil {
1521 return nil, err
1522 }
1523
1524 if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
1525 return nil, err
1526 }
1527
1528 var curve elliptic.Curve
1529 switch key.Curve {
1530 case "nistp256":
1531 curve = elliptic.P256()
1532 case "nistp384":
1533 curve = elliptic.P384()
1534 case "nistp521":
1535 curve = elliptic.P521()
1536 default:
1537 return nil, errors.New("ssh: unhandled elliptic curve: " + key.Curve)
1538 }
1539
1540 X, Y := elliptic.Unmarshal(curve, key.Pub)
1541 if X == nil || Y == nil {
1542 return nil, errors.New("ssh: failed to unmarshal public key")
1543 }
1544
1545 if key.D.Cmp(curve.Params().N) >= 0 {
1546 return nil, errors.New("ssh: scalar is out of range")
1547 }
1548
1549 x, y := curve.ScalarBaseMult(key.D.Bytes())
1550 if x.Cmp(X) != 0 || y.Cmp(Y) != 0 {
1551 return nil, errors.New("ssh: public key does not match private key")
1552 }
1553
1554 return &ecdsa.PrivateKey{
1555 PublicKey: ecdsa.PublicKey{
1556 Curve: curve,
1557 X: X,
1558 Y: Y,
1559 },
1560 D: key.D,
1561 }, nil
1562 default:
1563 return nil, errors.New("ssh: unhandled key type")
1564 }
1565 }
1566
1567 func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) {
1568 var w openSSHEncryptedPrivateKey
1569 var pk1 openSSHPrivateKey
1570
1571
1572 var check uint32
1573 if err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil {
1574 return nil, err
1575 }
1576
1577 pk1.Check1 = check
1578 pk1.Check2 = check
1579 w.NumKeys = 1
1580
1581
1582 if k, ok := key.(*ed25519.PrivateKey); ok {
1583 key = *k
1584 }
1585
1586 switch k := key.(type) {
1587 case *rsa.PrivateKey:
1588 E := new(big.Int).SetInt64(int64(k.PublicKey.E))
1589
1590
1591 pubKey := struct {
1592 KeyType string
1593 E *big.Int
1594 N *big.Int
1595 }{
1596 KeyAlgoRSA,
1597 E, k.PublicKey.N,
1598 }
1599 w.PubKey = Marshal(pubKey)
1600
1601
1602 key := openSSHRSAPrivateKey{
1603 N: k.PublicKey.N,
1604 E: E,
1605 D: k.D,
1606 Iqmp: k.Precomputed.Qinv,
1607 P: k.Primes[0],
1608 Q: k.Primes[1],
1609 Comment: comment,
1610 }
1611 pk1.Keytype = KeyAlgoRSA
1612 pk1.Rest = Marshal(key)
1613 case ed25519.PrivateKey:
1614 pub := make([]byte, ed25519.PublicKeySize)
1615 priv := make([]byte, ed25519.PrivateKeySize)
1616 copy(pub, k[32:])
1617 copy(priv, k)
1618
1619
1620 pubKey := struct {
1621 KeyType string
1622 Pub []byte
1623 }{
1624 KeyAlgoED25519, pub,
1625 }
1626 w.PubKey = Marshal(pubKey)
1627
1628
1629 key := openSSHEd25519PrivateKey{
1630 Pub: pub,
1631 Priv: priv,
1632 Comment: comment,
1633 }
1634 pk1.Keytype = KeyAlgoED25519
1635 pk1.Rest = Marshal(key)
1636 case *ecdsa.PrivateKey:
1637 var curve, keyType string
1638 switch name := k.Curve.Params().Name; name {
1639 case "P-256":
1640 curve = "nistp256"
1641 keyType = KeyAlgoECDSA256
1642 case "P-384":
1643 curve = "nistp384"
1644 keyType = KeyAlgoECDSA384
1645 case "P-521":
1646 curve = "nistp521"
1647 keyType = KeyAlgoECDSA521
1648 default:
1649 return nil, errors.New("ssh: unhandled elliptic curve " + name)
1650 }
1651
1652 pub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y)
1653
1654
1655 pubKey := struct {
1656 KeyType string
1657 Curve string
1658 Pub []byte
1659 }{
1660 keyType, curve, pub,
1661 }
1662 w.PubKey = Marshal(pubKey)
1663
1664
1665 key := openSSHECDSAPrivateKey{
1666 Curve: curve,
1667 Pub: pub,
1668 D: k.D,
1669 Comment: comment,
1670 }
1671 pk1.Keytype = keyType
1672 pk1.Rest = Marshal(key)
1673 default:
1674 return nil, fmt.Errorf("ssh: unsupported key type %T", k)
1675 }
1676
1677 var err error
1678
1679 w.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1))
1680 if err != nil {
1681 return nil, err
1682 }
1683
1684 b := Marshal(w)
1685 block := &pem.Block{
1686 Type: "OPENSSH PRIVATE KEY",
1687 Bytes: append([]byte(privateKeyAuthMagic), b...),
1688 }
1689 return block, nil
1690 }
1691
1692 func checkOpenSSHKeyPadding(pad []byte) error {
1693 for i, b := range pad {
1694 if int(b) != i+1 {
1695 return errors.New("ssh: padding not as expected")
1696 }
1697 }
1698 return nil
1699 }
1700
1701 func generateOpenSSHPadding(block []byte, blockSize int) []byte {
1702 for i, l := 0, len(block); (l+i)%blockSize != 0; i++ {
1703 block = append(block, byte(i+1))
1704 }
1705 return block
1706 }
1707
1708
1709
1710 func FingerprintLegacyMD5(pubKey PublicKey) string {
1711 md5sum := md5.Sum(pubKey.Marshal())
1712 hexarray := make([]string, len(md5sum))
1713 for i, c := range md5sum {
1714 hexarray[i] = hex.EncodeToString([]byte{c})
1715 }
1716 return strings.Join(hexarray, ":")
1717 }
1718
1719
1720
1721
1722
1723
1724 func FingerprintSHA256(pubKey PublicKey) string {
1725 sha256sum := sha256.Sum256(pubKey.Marshal())
1726 hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
1727 return "SHA256:" + hash
1728 }
1729
View as plain text