github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/net/smtp/smtp_test.go (about) 1 // Copyright 2010 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 smtp 6 7 import ( 8 "bufio" 9 "bytes" 10 "crypto/tls" 11 "crypto/x509" 12 "io" 13 "net" 14 "net/textproto" 15 "strings" 16 "testing" 17 "time" 18 ) 19 20 type authTest struct { 21 auth Auth 22 challenges []string 23 name string 24 responses []string 25 } 26 27 var authTests = []authTest{ 28 {PlainAuth("", "user", "pass", "testserver"), []string{}, "PLAIN", []string{"\x00user\x00pass"}}, 29 {PlainAuth("foo", "bar", "baz", "testserver"), []string{}, "PLAIN", []string{"foo\x00bar\x00baz"}}, 30 {CRAMMD5Auth("user", "pass"), []string{"<123456.1322876914@testserver>"}, "CRAM-MD5", []string{"", "user 287eb355114cf5c471c26a875f1ca4ae"}}, 31 } 32 33 func TestAuth(t *testing.T) { 34 testLoop: 35 for i, test := range authTests { 36 name, resp, err := test.auth.Start(&ServerInfo{"testserver", true, nil}) 37 if name != test.name { 38 t.Errorf("#%d got name %s, expected %s", i, name, test.name) 39 } 40 if !bytes.Equal(resp, []byte(test.responses[0])) { 41 t.Errorf("#%d got response %s, expected %s", i, resp, test.responses[0]) 42 } 43 if err != nil { 44 t.Errorf("#%d error: %s", i, err) 45 } 46 for j := range test.challenges { 47 challenge := []byte(test.challenges[j]) 48 expected := []byte(test.responses[j+1]) 49 resp, err := test.auth.Next(challenge, true) 50 if err != nil { 51 t.Errorf("#%d error: %s", i, err) 52 continue testLoop 53 } 54 if !bytes.Equal(resp, expected) { 55 t.Errorf("#%d got %s, expected %s", i, resp, expected) 56 continue testLoop 57 } 58 } 59 } 60 } 61 62 func TestAuthPlain(t *testing.T) { 63 auth := PlainAuth("foo", "bar", "baz", "servername") 64 65 tests := []struct { 66 server *ServerInfo 67 err string 68 }{ 69 { 70 server: &ServerInfo{Name: "servername", TLS: true}, 71 }, 72 { 73 // Okay; explicitly advertised by server. 74 server: &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}}, 75 }, 76 { 77 server: &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}}, 78 err: "unencrypted connection", 79 }, 80 { 81 server: &ServerInfo{Name: "attacker", TLS: true}, 82 err: "wrong host name", 83 }, 84 } 85 for i, tt := range tests { 86 _, _, err := auth.Start(tt.server) 87 got := "" 88 if err != nil { 89 got = err.Error() 90 } 91 if got != tt.err { 92 t.Errorf("%d. got error = %q; want %q", i, got, tt.err) 93 } 94 } 95 } 96 97 // Issue 17794: don't send a trailing space on AUTH command when there's no password. 98 func TestClientAuthTrimSpace(t *testing.T) { 99 server := "220 hello world\r\n" + 100 "200 some more" 101 var wrote bytes.Buffer 102 var fake faker 103 fake.ReadWriter = struct { 104 io.Reader 105 io.Writer 106 }{ 107 strings.NewReader(server), 108 &wrote, 109 } 110 c, err := NewClient(fake, "fake.host") 111 if err != nil { 112 t.Fatalf("NewClient: %v", err) 113 } 114 c.tls = true 115 c.didHello = true 116 c.Auth(toServerEmptyAuth{}) 117 c.Close() 118 if got, want := wrote.String(), "AUTH FOOAUTH\r\n*\r\nQUIT\r\n"; got != want { 119 t.Errorf("wrote %q; want %q", got, want) 120 } 121 } 122 123 // toServerEmptyAuth is an implementation of Auth that only implements 124 // the Start method, and returns "FOOAUTH", nil, nil. Notably, it returns 125 // zero bytes for "toServer" so we can test that we don't send spaces at 126 // the end of the line. See TestClientAuthTrimSpace. 127 type toServerEmptyAuth struct{} 128 129 func (toServerEmptyAuth) Start(server *ServerInfo) (proto string, toServer []byte, err error) { 130 return "FOOAUTH", nil, nil 131 } 132 133 func (toServerEmptyAuth) Next(fromServer []byte, more bool) (toServer []byte, err error) { 134 panic("unexpected call") 135 } 136 137 type faker struct { 138 io.ReadWriter 139 } 140 141 func (f faker) Close() error { return nil } 142 func (f faker) LocalAddr() net.Addr { return nil } 143 func (f faker) RemoteAddr() net.Addr { return nil } 144 func (f faker) SetDeadline(time.Time) error { return nil } 145 func (f faker) SetReadDeadline(time.Time) error { return nil } 146 func (f faker) SetWriteDeadline(time.Time) error { return nil } 147 148 func TestBasic(t *testing.T) { 149 server := strings.Join(strings.Split(basicServer, "\n"), "\r\n") 150 client := strings.Join(strings.Split(basicClient, "\n"), "\r\n") 151 152 var cmdbuf bytes.Buffer 153 bcmdbuf := bufio.NewWriter(&cmdbuf) 154 var fake faker 155 fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf) 156 c := &Client{Text: textproto.NewConn(fake), localName: "localhost"} 157 158 if err := c.helo(); err != nil { 159 t.Fatalf("HELO failed: %s", err) 160 } 161 if err := c.ehlo(); err == nil { 162 t.Fatalf("Expected first EHLO to fail") 163 } 164 if err := c.ehlo(); err != nil { 165 t.Fatalf("Second EHLO failed: %s", err) 166 } 167 168 c.didHello = true 169 if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" { 170 t.Fatalf("Expected AUTH supported") 171 } 172 if ok, _ := c.Extension("DSN"); ok { 173 t.Fatalf("Shouldn't support DSN") 174 } 175 176 if err := c.Mail("user@gmail.com"); err == nil { 177 t.Fatalf("MAIL should require authentication") 178 } 179 180 if err := c.Verify("user1@gmail.com"); err == nil { 181 t.Fatalf("First VRFY: expected no verification") 182 } 183 if err := c.Verify("user2@gmail.com"); err != nil { 184 t.Fatalf("Second VRFY: expected verification, got %s", err) 185 } 186 187 // fake TLS so authentication won't complain 188 c.tls = true 189 c.serverName = "smtp.google.com" 190 if err := c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")); err != nil { 191 t.Fatalf("AUTH failed: %s", err) 192 } 193 194 if err := c.Mail("user@gmail.com"); err != nil { 195 t.Fatalf("MAIL failed: %s", err) 196 } 197 if err := c.Rcpt("golang-nuts@googlegroups.com"); err != nil { 198 t.Fatalf("RCPT failed: %s", err) 199 } 200 msg := `From: user@gmail.com 201 To: golang-nuts@googlegroups.com 202 Subject: Hooray for Go 203 204 Line 1 205 .Leading dot line . 206 Goodbye.` 207 w, err := c.Data() 208 if err != nil { 209 t.Fatalf("DATA failed: %s", err) 210 } 211 if _, err := w.Write([]byte(msg)); err != nil { 212 t.Fatalf("Data write failed: %s", err) 213 } 214 if err := w.Close(); err != nil { 215 t.Fatalf("Bad data response: %s", err) 216 } 217 218 if err := c.Quit(); err != nil { 219 t.Fatalf("QUIT failed: %s", err) 220 } 221 222 bcmdbuf.Flush() 223 actualcmds := cmdbuf.String() 224 if client != actualcmds { 225 t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client) 226 } 227 } 228 229 var basicServer = `250 mx.google.com at your service 230 502 Unrecognized command. 231 250-mx.google.com at your service 232 250-SIZE 35651584 233 250-AUTH LOGIN PLAIN 234 250 8BITMIME 235 530 Authentication required 236 252 Send some mail, I'll try my best 237 250 User is valid 238 235 Accepted 239 250 Sender OK 240 250 Receiver OK 241 354 Go ahead 242 250 Data OK 243 221 OK 244 ` 245 246 var basicClient = `HELO localhost 247 EHLO localhost 248 EHLO localhost 249 MAIL FROM:<user@gmail.com> BODY=8BITMIME 250 VRFY user1@gmail.com 251 VRFY user2@gmail.com 252 AUTH PLAIN AHVzZXIAcGFzcw== 253 MAIL FROM:<user@gmail.com> BODY=8BITMIME 254 RCPT TO:<golang-nuts@googlegroups.com> 255 DATA 256 From: user@gmail.com 257 To: golang-nuts@googlegroups.com 258 Subject: Hooray for Go 259 260 Line 1 261 ..Leading dot line . 262 Goodbye. 263 . 264 QUIT 265 ` 266 267 func TestNewClient(t *testing.T) { 268 server := strings.Join(strings.Split(newClientServer, "\n"), "\r\n") 269 client := strings.Join(strings.Split(newClientClient, "\n"), "\r\n") 270 271 var cmdbuf bytes.Buffer 272 bcmdbuf := bufio.NewWriter(&cmdbuf) 273 out := func() string { 274 bcmdbuf.Flush() 275 return cmdbuf.String() 276 } 277 var fake faker 278 fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf) 279 c, err := NewClient(fake, "fake.host") 280 if err != nil { 281 t.Fatalf("NewClient: %v\n(after %v)", err, out()) 282 } 283 defer c.Close() 284 if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" { 285 t.Fatalf("Expected AUTH supported") 286 } 287 if ok, _ := c.Extension("DSN"); ok { 288 t.Fatalf("Shouldn't support DSN") 289 } 290 if err := c.Quit(); err != nil { 291 t.Fatalf("QUIT failed: %s", err) 292 } 293 294 actualcmds := out() 295 if client != actualcmds { 296 t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client) 297 } 298 } 299 300 var newClientServer = `220 hello world 301 250-mx.google.com at your service 302 250-SIZE 35651584 303 250-AUTH LOGIN PLAIN 304 250 8BITMIME 305 221 OK 306 ` 307 308 var newClientClient = `EHLO localhost 309 QUIT 310 ` 311 312 func TestNewClient2(t *testing.T) { 313 server := strings.Join(strings.Split(newClient2Server, "\n"), "\r\n") 314 client := strings.Join(strings.Split(newClient2Client, "\n"), "\r\n") 315 316 var cmdbuf bytes.Buffer 317 bcmdbuf := bufio.NewWriter(&cmdbuf) 318 var fake faker 319 fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf) 320 c, err := NewClient(fake, "fake.host") 321 if err != nil { 322 t.Fatalf("NewClient: %v", err) 323 } 324 defer c.Close() 325 if ok, _ := c.Extension("DSN"); ok { 326 t.Fatalf("Shouldn't support DSN") 327 } 328 if err := c.Quit(); err != nil { 329 t.Fatalf("QUIT failed: %s", err) 330 } 331 332 bcmdbuf.Flush() 333 actualcmds := cmdbuf.String() 334 if client != actualcmds { 335 t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client) 336 } 337 } 338 339 var newClient2Server = `220 hello world 340 502 EH? 341 250-mx.google.com at your service 342 250-SIZE 35651584 343 250-AUTH LOGIN PLAIN 344 250 8BITMIME 345 221 OK 346 ` 347 348 var newClient2Client = `EHLO localhost 349 HELO localhost 350 QUIT 351 ` 352 353 func TestHello(t *testing.T) { 354 355 if len(helloServer) != len(helloClient) { 356 t.Fatalf("Hello server and client size mismatch") 357 } 358 359 for i := 0; i < len(helloServer); i++ { 360 server := strings.Join(strings.Split(baseHelloServer+helloServer[i], "\n"), "\r\n") 361 client := strings.Join(strings.Split(baseHelloClient+helloClient[i], "\n"), "\r\n") 362 var cmdbuf bytes.Buffer 363 bcmdbuf := bufio.NewWriter(&cmdbuf) 364 var fake faker 365 fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf) 366 c, err := NewClient(fake, "fake.host") 367 if err != nil { 368 t.Fatalf("NewClient: %v", err) 369 } 370 defer c.Close() 371 c.localName = "customhost" 372 err = nil 373 374 switch i { 375 case 0: 376 err = c.Hello("customhost") 377 case 1: 378 err = c.StartTLS(nil) 379 if err.Error() == "502 Not implemented" { 380 err = nil 381 } 382 case 2: 383 err = c.Verify("test@example.com") 384 case 3: 385 c.tls = true 386 c.serverName = "smtp.google.com" 387 err = c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")) 388 case 4: 389 err = c.Mail("test@example.com") 390 case 5: 391 ok, _ := c.Extension("feature") 392 if ok { 393 t.Errorf("Expected FEATURE not to be supported") 394 } 395 case 6: 396 err = c.Reset() 397 case 7: 398 err = c.Quit() 399 case 8: 400 err = c.Verify("test@example.com") 401 if err != nil { 402 err = c.Hello("customhost") 403 if err != nil { 404 t.Errorf("Want error, got none") 405 } 406 } 407 default: 408 t.Fatalf("Unhandled command") 409 } 410 411 if err != nil { 412 t.Errorf("Command %d failed: %v", i, err) 413 } 414 415 bcmdbuf.Flush() 416 actualcmds := cmdbuf.String() 417 if client != actualcmds { 418 t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client) 419 } 420 } 421 } 422 423 var baseHelloServer = `220 hello world 424 502 EH? 425 250-mx.google.com at your service 426 250 FEATURE 427 ` 428 429 var helloServer = []string{ 430 "", 431 "502 Not implemented\n", 432 "250 User is valid\n", 433 "235 Accepted\n", 434 "250 Sender ok\n", 435 "", 436 "250 Reset ok\n", 437 "221 Goodbye\n", 438 "250 Sender ok\n", 439 } 440 441 var baseHelloClient = `EHLO customhost 442 HELO customhost 443 ` 444 445 var helloClient = []string{ 446 "", 447 "STARTTLS\n", 448 "VRFY test@example.com\n", 449 "AUTH PLAIN AHVzZXIAcGFzcw==\n", 450 "MAIL FROM:<test@example.com>\n", 451 "", 452 "RSET\n", 453 "QUIT\n", 454 "VRFY test@example.com\n", 455 } 456 457 func TestSendMail(t *testing.T) { 458 server := strings.Join(strings.Split(sendMailServer, "\n"), "\r\n") 459 client := strings.Join(strings.Split(sendMailClient, "\n"), "\r\n") 460 var cmdbuf bytes.Buffer 461 bcmdbuf := bufio.NewWriter(&cmdbuf) 462 l, err := net.Listen("tcp", "127.0.0.1:0") 463 if err != nil { 464 t.Fatalf("Unable to to create listener: %v", err) 465 } 466 defer l.Close() 467 468 // prevent data race on bcmdbuf 469 var done = make(chan struct{}) 470 go func(data []string) { 471 472 defer close(done) 473 474 conn, err := l.Accept() 475 if err != nil { 476 t.Errorf("Accept error: %v", err) 477 return 478 } 479 defer conn.Close() 480 481 tc := textproto.NewConn(conn) 482 for i := 0; i < len(data) && data[i] != ""; i++ { 483 tc.PrintfLine(data[i]) 484 for len(data[i]) >= 4 && data[i][3] == '-' { 485 i++ 486 tc.PrintfLine(data[i]) 487 } 488 if data[i] == "221 Goodbye" { 489 return 490 } 491 read := false 492 for !read || data[i] == "354 Go ahead" { 493 msg, err := tc.ReadLine() 494 bcmdbuf.Write([]byte(msg + "\r\n")) 495 read = true 496 if err != nil { 497 t.Errorf("Read error: %v", err) 498 return 499 } 500 if data[i] == "354 Go ahead" && msg == "." { 501 break 502 } 503 } 504 } 505 }(strings.Split(server, "\r\n")) 506 507 err = SendMail(l.Addr().String(), nil, "test@example.com", []string{"other@example.com"}, []byte(strings.Replace(`From: test@example.com 508 To: other@example.com 509 Subject: SendMail test 510 511 SendMail is working for me. 512 `, "\n", "\r\n", -1))) 513 514 if err != nil { 515 t.Errorf("%v", err) 516 } 517 518 <-done 519 bcmdbuf.Flush() 520 actualcmds := cmdbuf.String() 521 if client != actualcmds { 522 t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client) 523 } 524 } 525 526 var sendMailServer = `220 hello world 527 502 EH? 528 250 mx.google.com at your service 529 250 Sender ok 530 250 Receiver ok 531 354 Go ahead 532 250 Data ok 533 221 Goodbye 534 ` 535 536 var sendMailClient = `EHLO localhost 537 HELO localhost 538 MAIL FROM:<test@example.com> 539 RCPT TO:<other@example.com> 540 DATA 541 From: test@example.com 542 To: other@example.com 543 Subject: SendMail test 544 545 SendMail is working for me. 546 . 547 QUIT 548 ` 549 550 func TestAuthFailed(t *testing.T) { 551 server := strings.Join(strings.Split(authFailedServer, "\n"), "\r\n") 552 client := strings.Join(strings.Split(authFailedClient, "\n"), "\r\n") 553 var cmdbuf bytes.Buffer 554 bcmdbuf := bufio.NewWriter(&cmdbuf) 555 var fake faker 556 fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf) 557 c, err := NewClient(fake, "fake.host") 558 if err != nil { 559 t.Fatalf("NewClient: %v", err) 560 } 561 defer c.Close() 562 563 c.tls = true 564 c.serverName = "smtp.google.com" 565 err = c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")) 566 567 if err == nil { 568 t.Error("Auth: expected error; got none") 569 } else if err.Error() != "535 Invalid credentials\nplease see www.example.com" { 570 t.Errorf("Auth: got error: %v, want: %s", err, "535 Invalid credentials\nplease see www.example.com") 571 } 572 573 bcmdbuf.Flush() 574 actualcmds := cmdbuf.String() 575 if client != actualcmds { 576 t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client) 577 } 578 } 579 580 var authFailedServer = `220 hello world 581 250-mx.google.com at your service 582 250 AUTH LOGIN PLAIN 583 535-Invalid credentials 584 535 please see www.example.com 585 221 Goodbye 586 ` 587 588 var authFailedClient = `EHLO localhost 589 AUTH PLAIN AHVzZXIAcGFzcw== 590 * 591 QUIT 592 ` 593 594 func TestTLSClient(t *testing.T) { 595 ln := newLocalListener(t) 596 defer ln.Close() 597 errc := make(chan error) 598 go func() { 599 errc <- sendMail(ln.Addr().String()) 600 }() 601 conn, err := ln.Accept() 602 if err != nil { 603 t.Fatalf("failed to accept connection: %v", err) 604 } 605 defer conn.Close() 606 if err := serverHandle(conn, t); err != nil { 607 t.Fatalf("failed to handle connection: %v", err) 608 } 609 if err := <-errc; err != nil { 610 t.Fatalf("client error: %v", err) 611 } 612 } 613 614 func TestTLSConnState(t *testing.T) { 615 ln := newLocalListener(t) 616 defer ln.Close() 617 clientDone := make(chan bool) 618 serverDone := make(chan bool) 619 go func() { 620 defer close(serverDone) 621 c, err := ln.Accept() 622 if err != nil { 623 t.Errorf("Server accept: %v", err) 624 return 625 } 626 defer c.Close() 627 if err := serverHandle(c, t); err != nil { 628 t.Errorf("server error: %v", err) 629 } 630 }() 631 go func() { 632 defer close(clientDone) 633 c, err := Dial(ln.Addr().String()) 634 if err != nil { 635 t.Errorf("Client dial: %v", err) 636 return 637 } 638 defer c.Quit() 639 cfg := &tls.Config{ServerName: "example.com"} 640 testHookStartTLS(cfg) // set the RootCAs 641 if err := c.StartTLS(cfg); err != nil { 642 t.Errorf("StartTLS: %v", err) 643 return 644 } 645 cs, ok := c.TLSConnectionState() 646 if !ok { 647 t.Errorf("TLSConnectionState returned ok == false; want true") 648 return 649 } 650 if cs.Version == 0 || !cs.HandshakeComplete { 651 t.Errorf("ConnectionState = %#v; expect non-zero Version and HandshakeComplete", cs) 652 } 653 }() 654 <-clientDone 655 <-serverDone 656 } 657 658 func newLocalListener(t *testing.T) net.Listener { 659 ln, err := net.Listen("tcp", "127.0.0.1:0") 660 if err != nil { 661 ln, err = net.Listen("tcp6", "[::1]:0") 662 } 663 if err != nil { 664 t.Fatal(err) 665 } 666 return ln 667 } 668 669 type smtpSender struct { 670 w io.Writer 671 } 672 673 func (s smtpSender) send(f string) { 674 s.w.Write([]byte(f + "\r\n")) 675 } 676 677 // smtp server, finely tailored to deal with our own client only! 678 func serverHandle(c net.Conn, t *testing.T) error { 679 send := smtpSender{c}.send 680 send("220 127.0.0.1 ESMTP service ready") 681 s := bufio.NewScanner(c) 682 for s.Scan() { 683 switch s.Text() { 684 case "EHLO localhost": 685 send("250-127.0.0.1 ESMTP offers a warm hug of welcome") 686 send("250-STARTTLS") 687 send("250 Ok") 688 case "STARTTLS": 689 send("220 Go ahead") 690 keypair, err := tls.X509KeyPair(localhostCert, localhostKey) 691 if err != nil { 692 return err 693 } 694 config := &tls.Config{Certificates: []tls.Certificate{keypair}} 695 c = tls.Server(c, config) 696 defer c.Close() 697 return serverHandleTLS(c, t) 698 default: 699 t.Fatalf("unrecognized command: %q", s.Text()) 700 } 701 } 702 return s.Err() 703 } 704 705 func serverHandleTLS(c net.Conn, t *testing.T) error { 706 send := smtpSender{c}.send 707 s := bufio.NewScanner(c) 708 for s.Scan() { 709 switch s.Text() { 710 case "EHLO localhost": 711 send("250 Ok") 712 case "MAIL FROM:<joe1@example.com>": 713 send("250 Ok") 714 case "RCPT TO:<joe2@example.com>": 715 send("250 Ok") 716 case "DATA": 717 send("354 send the mail data, end with .") 718 send("250 Ok") 719 case "Subject: test": 720 case "": 721 case "howdy!": 722 case ".": 723 case "QUIT": 724 send("221 127.0.0.1 Service closing transmission channel") 725 return nil 726 default: 727 t.Fatalf("unrecognized command during TLS: %q", s.Text()) 728 } 729 } 730 return s.Err() 731 } 732 733 func init() { 734 testRootCAs := x509.NewCertPool() 735 testRootCAs.AppendCertsFromPEM(localhostCert) 736 testHookStartTLS = func(config *tls.Config) { 737 config.RootCAs = testRootCAs 738 } 739 } 740 741 func sendMail(hostPort string) error { 742 host, _, err := net.SplitHostPort(hostPort) 743 if err != nil { 744 return err 745 } 746 auth := PlainAuth("", "", "", host) 747 from := "joe1@example.com" 748 to := []string{"joe2@example.com"} 749 return SendMail(hostPort, auth, from, to, []byte("Subject: test\n\nhowdy!")) 750 } 751 752 // (copied from net/http/httptest) 753 // localhostCert is a PEM-encoded TLS cert with SAN IPs 754 // "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end 755 // of ASN.1 time). 756 // generated from src/crypto/tls: 757 // go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h 758 var localhostCert = []byte(`-----BEGIN CERTIFICATE----- 759 MIIBjjCCATigAwIBAgIQMon9v0s3pDFXvAMnPgelpzANBgkqhkiG9w0BAQsFADAS 760 MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw 761 MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB 762 AM0u/mNXKkhAzNsFkwKZPSpC4lZZaePQ55IyaJv3ovMM2smvthnlqaUfVKVmz7FF 763 wLP9csX6vGtvkZg1uWAtvfkCAwEAAaNoMGYwDgYDVR0PAQH/BAQDAgKkMBMGA1Ud 764 JQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhh 765 bXBsZS5jb22HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQAD 766 QQBOZsFVC7IwX+qibmSbt2IPHkUgXhfbq0a9MYhD6tHcj4gbDcTXh4kZCbgHCz22 767 gfSj2/G2wxzopoISVDucuncj 768 -----END CERTIFICATE-----`) 769 770 // localhostKey is the private key for localhostCert. 771 var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY----- 772 MIIBOwIBAAJBAM0u/mNXKkhAzNsFkwKZPSpC4lZZaePQ55IyaJv3ovMM2smvthnl 773 qaUfVKVmz7FFwLP9csX6vGtvkZg1uWAtvfkCAwEAAQJART2qkxODLUbQ2siSx7m2 774 rmBLyR/7X+nLe8aPDrMOxj3heDNl4YlaAYLexbcY8d7VDfCRBKYoAOP0UCP1Vhuf 775 UQIhAO6PEI55K3SpNIdc2k5f0xz+9rodJCYzu51EwWX7r8ufAiEA3C9EkLiU2NuK 776 3L3DHCN5IlUSN1Nr/lw8NIt50Yorj2cCIQCDw1VbvCV6bDLtSSXzAA51B4ZzScE7 777 sHtB5EYF9Dwm9QIhAJuCquuH4mDzVjUntXjXOQPdj7sRqVGCNWdrJwOukat7AiAy 778 LXLEwb77DIPoI5ZuaXQC+MnyyJj1ExC9RFcGz+bexA== 779 -----END RSA PRIVATE KEY-----`)