File tree Expand file tree Collapse file tree 4 files changed +45
-10
lines changed Expand file tree Collapse file tree 4 files changed +45
-10
lines changed Original file line number Diff line number Diff line change @@ -670,3 +670,10 @@ func (c *Conn) PeerCertificates() []*x509.Certificate {
670
670
671
671
return c .peerCertificates
672
672
}
673
+
674
+ // VerifyHostname checks that the peer certificate chain is valid for
675
+ // connecting to host. If so, it returns nil; if not, it returns an os.Error
676
+ // describing the problem.
677
+ func (c * Conn ) VerifyHostname (host string ) os.Error {
678
+ return c .PeerCertificates ()[0 ].VerifyHostname (host )
679
+ }
Original file line number Diff line number Diff line change @@ -426,19 +426,37 @@ func matchHostnames(pattern, host string) bool {
426
426
return true
427
427
}
428
428
429
- // IsValidForHost returns true iff c is a valid certificate for the given host.
430
- func (c * Certificate ) IsValidForHost (h string ) bool {
429
+ type HostnameError struct {
430
+ Certificate * Certificate
431
+ Host string
432
+ }
433
+
434
+ func (h * HostnameError ) String () string {
435
+ var valid string
436
+ c := h .Certificate
437
+ if len (c .DNSNames ) > 0 {
438
+ valid = strings .Join (c .DNSNames , ", " )
439
+ } else {
440
+ valid = c .Subject .CommonName
441
+ }
442
+ return "certificate is valid for " + valid + ", not " + h .Host
443
+ }
444
+
445
+ // VerifyHostname returns nil if c is a valid certificate for the named host.
446
+ // Otherwise it returns an os.Error describing the mismatch.
447
+ func (c * Certificate ) VerifyHostname (h string ) os.Error {
431
448
if len (c .DNSNames ) > 0 {
432
449
for _ , match := range c .DNSNames {
433
450
if matchHostnames (match , h ) {
434
- return true
451
+ return nil
435
452
}
436
453
}
437
454
// If Subject Alt Name is given, we ignore the common name.
438
- return false
455
+ } else if matchHostnames (c .Subject .CommonName , h ) {
456
+ return nil
439
457
}
440
458
441
- return matchHostnames ( c . Subject . CommonName , h )
459
+ return & HostnameError { c , h }
442
460
}
443
461
444
462
type UnhandledCriticalExtension struct {}
Original file line number Diff line number Diff line change @@ -96,8 +96,8 @@ func TestCertificateParse(t *testing.T) {
96
96
t .Error (err )
97
97
}
98
98
99
- if ! certs [0 ].IsValidForHost ("mail.google.com" ) {
100
- t .Errorf ( "cert not valid for host" )
99
+ if err := certs [0 ].VerifyHostname ("mail.google.com" ); err != nil {
100
+ t .Error ( err )
101
101
}
102
102
}
103
103
Original file line number Diff line number Diff line change @@ -59,11 +59,21 @@ func send(req *Request) (resp *Response, err os.Error) {
59
59
var conn io.ReadWriteCloser
60
60
if req .URL .Scheme == "http" {
61
61
conn , err = net .Dial ("tcp" , "" , addr )
62
+ if err != nil {
63
+ return nil , err
64
+ }
62
65
} else { // https
63
66
conn , err = tls .Dial ("tcp" , "" , addr )
64
- }
65
- if err != nil {
66
- return nil , err
67
+ if err != nil {
68
+ return nil , err
69
+ }
70
+ h := req .URL .Host
71
+ if hasPort (h ) {
72
+ h = h [0 :strings .LastIndex (h , ":" )]
73
+ }
74
+ if err := conn .(* tls.Conn ).VerifyHostname (h ); err != nil {
75
+ return nil , err
76
+ }
67
77
}
68
78
69
79
err = req .Write (conn )
You can’t perform that action at this time.
0 commit comments