certs_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2013 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. package ssh
  5. import (
  6. "bytes"
  7. "crypto/rand"
  8. "testing"
  9. "time"
  10. )
  11. // Cert generated by ssh-keygen 6.0p1 Debian-4.
  12. // % ssh-keygen -s ca-key -I test user-key
  13. var exampleSSHCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=`
  14. func TestParseCert(t *testing.T) {
  15. authKeyBytes := []byte(exampleSSHCert)
  16. key, _, _, rest, err := ParseAuthorizedKey(authKeyBytes)
  17. if err != nil {
  18. t.Fatalf("ParseAuthorizedKey: %v", err)
  19. }
  20. if len(rest) > 0 {
  21. t.Errorf("rest: got %q, want empty", rest)
  22. }
  23. if _, ok := key.(*Certificate); !ok {
  24. t.Fatalf("got %#v, want *Certificate", key)
  25. }
  26. marshaled := MarshalAuthorizedKey(key)
  27. // Before comparison, remove the trailing newline that
  28. // MarshalAuthorizedKey adds.
  29. marshaled = marshaled[:len(marshaled)-1]
  30. if !bytes.Equal(authKeyBytes, marshaled) {
  31. t.Errorf("marshaled certificate does not match original: got %q, want %q", marshaled, authKeyBytes)
  32. }
  33. }
  34. func TestValidateCert(t *testing.T) {
  35. key, _, _, _, err := ParseAuthorizedKey([]byte(exampleSSHCert))
  36. if err != nil {
  37. t.Fatalf("ParseAuthorizedKey: %v", err)
  38. }
  39. validCert, ok := key.(*Certificate)
  40. if !ok {
  41. t.Fatalf("got %v (%T), want *Certificate", key, key)
  42. }
  43. checker := CertChecker{}
  44. checker.IsAuthority = func(k PublicKey) bool {
  45. return bytes.Equal(k.Marshal(), validCert.SignatureKey.Marshal())
  46. }
  47. if err := checker.CheckCert("user", validCert); err != nil {
  48. t.Errorf("Unable to validate certificate: %v", err)
  49. }
  50. invalidCert := &Certificate{
  51. Key: testPublicKeys["rsa"],
  52. SignatureKey: testPublicKeys["ecdsa"],
  53. ValidBefore: CertTimeInfinity,
  54. Signature: &Signature{},
  55. }
  56. if err := checker.CheckCert("user", invalidCert); err == nil {
  57. t.Error("Invalid cert signature passed validation")
  58. }
  59. }
  60. func TestValidateCertTime(t *testing.T) {
  61. cert := Certificate{
  62. ValidPrincipals: []string{"user"},
  63. Key: testPublicKeys["rsa"],
  64. ValidAfter: 50,
  65. ValidBefore: 100,
  66. }
  67. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  68. for ts, ok := range map[int64]bool{
  69. 25: false,
  70. 50: true,
  71. 99: true,
  72. 100: false,
  73. 125: false,
  74. } {
  75. checker := CertChecker{
  76. Clock: func() time.Time { return time.Unix(ts, 0) },
  77. }
  78. checker.IsAuthority = func(k PublicKey) bool {
  79. return bytes.Equal(k.Marshal(),
  80. testPublicKeys["ecdsa"].Marshal())
  81. }
  82. if v := checker.CheckCert("user", &cert); (v == nil) != ok {
  83. t.Errorf("Authenticate(%d): %v", ts, v)
  84. }
  85. }
  86. }
  87. // TODO(hanwen): tests for
  88. //
  89. // host keys:
  90. // * fallbacks
  91. func TestHostKeyCert(t *testing.T) {
  92. cert := &Certificate{
  93. ValidPrincipals: []string{"hostname", "hostname.domain"},
  94. Key: testPublicKeys["rsa"],
  95. ValidBefore: CertTimeInfinity,
  96. CertType: HostCert,
  97. }
  98. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  99. checker := &CertChecker{
  100. IsAuthority: func(p PublicKey) bool {
  101. return bytes.Equal(testPublicKeys["ecdsa"].Marshal(), p.Marshal())
  102. },
  103. }
  104. certSigner, err := NewCertSigner(cert, testSigners["rsa"])
  105. if err != nil {
  106. t.Errorf("NewCertSigner: %v", err)
  107. }
  108. for _, name := range []string{"hostname", "otherhost"} {
  109. c1, c2, err := netPipe()
  110. if err != nil {
  111. t.Fatalf("netPipe: %v", err)
  112. }
  113. defer c1.Close()
  114. defer c2.Close()
  115. go func() {
  116. conf := ServerConfig{
  117. NoClientAuth: true,
  118. }
  119. conf.AddHostKey(certSigner)
  120. _, _, _, err := NewServerConn(c1, &conf)
  121. if err != nil {
  122. t.Fatalf("NewServerConn: %v", err)
  123. }
  124. }()
  125. config := &ClientConfig{
  126. User: "user",
  127. HostKeyCallback: checker.CheckHostKey,
  128. }
  129. _, _, _, err = NewClientConn(c2, name, config)
  130. succeed := name == "hostname"
  131. if (err == nil) != succeed {
  132. t.Fatalf("NewClientConn(%q): %v", name, err)
  133. }
  134. }
  135. }