diff options
author | jsing <> | 2015-10-13 13:58:33 +0000 |
---|---|---|
committer | jsing <> | 2015-10-13 13:58:33 +0000 |
commit | 3fbbb904dc901d145acacf52cc84f593f1b4be38 (patch) | |
tree | ec234009d935148c3e2ccbbd60d5a54c2a29aef0 /src | |
parent | a4abefbb1d275afbf70665550417fa7200dd77d8 (diff) | |
download | openbsd-3fbbb904dc901d145acacf52cc84f593f1b4be38.tar.gz openbsd-3fbbb904dc901d145acacf52cc84f593f1b4be38.tar.bz2 openbsd-3fbbb904dc901d145acacf52cc84f593f1b4be38.zip |
Add test coverage for peer certificate info and connection info.
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libtls/gotls/tls.go | 79 | ||||
-rw-r--r-- | src/regress/lib/libtls/gotls/tls_test.go | 158 |
2 files changed, 231 insertions, 6 deletions
diff --git a/src/regress/lib/libtls/gotls/tls.go b/src/regress/lib/libtls/gotls/tls.go index 6dc51b8922..74c34b4064 100644 --- a/src/regress/lib/libtls/gotls/tls.go +++ b/src/regress/lib/libtls/gotls/tls.go | |||
@@ -15,6 +15,7 @@ import "C" | |||
15 | import ( | 15 | import ( |
16 | "errors" | 16 | "errors" |
17 | "fmt" | 17 | "fmt" |
18 | "time" | ||
18 | "unsafe" | 19 | "unsafe" |
19 | ) | 20 | ) |
20 | 21 | ||
@@ -115,6 +116,84 @@ func (t *TLS) Error() string { | |||
115 | return "" | 116 | return "" |
116 | } | 117 | } |
117 | 118 | ||
119 | // PeerCertProvided returns whether the peer provided a certificate. | ||
120 | func (t *TLS) PeerCertProvided() bool { | ||
121 | return C.tls_peer_cert_provided(t.ctx) == 1 | ||
122 | } | ||
123 | |||
124 | // PeerCertContainsName checks whether the peer certificate contains | ||
125 | // the specified name. | ||
126 | func (t *TLS) PeerCertContainsName(name string) bool { | ||
127 | n := C.CString(name) | ||
128 | defer C.free(unsafe.Pointer(n)) | ||
129 | return C.tls_peer_cert_contains_name(t.ctx, n) == 1 | ||
130 | } | ||
131 | |||
132 | // PeerCertIssuer returns the issuer of the peer certificate. | ||
133 | func (t *TLS) PeerCertIssuer() (string, error) { | ||
134 | issuer := C.tls_peer_cert_issuer(t.ctx) | ||
135 | if issuer == nil { | ||
136 | return "", errors.New("no issuer returned") | ||
137 | } | ||
138 | return C.GoString(issuer), nil | ||
139 | } | ||
140 | |||
141 | // PeerCertSubject returns the subject of the peer certificate. | ||
142 | func (t *TLS) PeerCertSubject() (string, error) { | ||
143 | subject := C.tls_peer_cert_subject(t.ctx) | ||
144 | if subject == nil { | ||
145 | return "", errors.New("no subject returned") | ||
146 | } | ||
147 | return C.GoString(subject), nil | ||
148 | } | ||
149 | |||
150 | // PeerCertHash returns a hash of the peer certificate. | ||
151 | func (t *TLS) PeerCertHash() (string, error) { | ||
152 | hash := C.tls_peer_cert_hash(t.ctx) | ||
153 | if hash == nil { | ||
154 | return "", errors.New("no hash returned") | ||
155 | } | ||
156 | return C.GoString(hash), nil | ||
157 | } | ||
158 | |||
159 | // PeerCertNotBefore returns the notBefore time from the peer | ||
160 | // certificate. | ||
161 | func (t *TLS) PeerCertNotBefore() (time.Time, error) { | ||
162 | notBefore := C.tls_peer_cert_notbefore(t.ctx) | ||
163 | if notBefore == -1 { | ||
164 | return time.Time{}, errors.New("no notBefore time returned") | ||
165 | } | ||
166 | return time.Unix(int64(notBefore), 0), nil | ||
167 | } | ||
168 | |||
169 | // PeerCertNotAfter returns the notAfter time from the peer | ||
170 | // certificate. | ||
171 | func (t *TLS) PeerCertNotAfter() (time.Time, error) { | ||
172 | notAfter := C.tls_peer_cert_notafter(t.ctx) | ||
173 | if notAfter == -1 { | ||
174 | return time.Time{}, errors.New("no notAfter time") | ||
175 | } | ||
176 | return time.Unix(int64(notAfter), 0), nil | ||
177 | } | ||
178 | |||
179 | // ConnVersion returns the protocol version of the connection. | ||
180 | func (t *TLS) ConnVersion() (string, error) { | ||
181 | ver := C.tls_conn_version(t.ctx) | ||
182 | if ver == nil { | ||
183 | return "", errors.New("no connection version") | ||
184 | } | ||
185 | return C.GoString(ver), nil | ||
186 | } | ||
187 | |||
188 | // ConnCipher returns the cipher suite used for the connection. | ||
189 | func (t *TLS) ConnCipher() (string, error) { | ||
190 | cipher := C.tls_conn_cipher(t.ctx) | ||
191 | if cipher == nil { | ||
192 | return "", errors.New("no connection cipher") | ||
193 | } | ||
194 | return C.GoString(cipher), nil | ||
195 | } | ||
196 | |||
118 | // Connect attempts to establish an TLS connection to the specified host on | 197 | // Connect attempts to establish an TLS connection to the specified host on |
119 | // the given port. The host may optionally contain a colon separated port | 198 | // the given port. The host may optionally contain a colon separated port |
120 | // value if the port string is specified as an empty string. | 199 | // value if the port string is specified as an empty string. |
diff --git a/src/regress/lib/libtls/gotls/tls_test.go b/src/regress/lib/libtls/gotls/tls_test.go index 2afcf93212..2331ec0be6 100644 --- a/src/regress/lib/libtls/gotls/tls_test.go +++ b/src/regress/lib/libtls/gotls/tls_test.go | |||
@@ -10,6 +10,18 @@ import ( | |||
10 | "os" | 10 | "os" |
11 | "strings" | 11 | "strings" |
12 | "testing" | 12 | "testing" |
13 | "time" | ||
14 | ) | ||
15 | |||
16 | const ( | ||
17 | httpContent = "Hello, TLS!" | ||
18 | |||
19 | certHash = "SHA256:448f628a8a65aa18560e53a80c53acb38c51b427df0334082349141147dc9bf6" | ||
20 | ) | ||
21 | |||
22 | var ( | ||
23 | certNotBefore = time.Unix(0, 0) | ||
24 | certNotAfter = certNotBefore.Add(1000000 * time.Hour) | ||
13 | ) | 25 | ) |
14 | 26 | ||
15 | // createCAFile writes a PEM encoded version of the certificate out to a | 27 | // createCAFile writes a PEM encoded version of the certificate out to a |
@@ -30,9 +42,7 @@ func createCAFile(cert []byte) (string, error) { | |||
30 | return f.Name(), nil | 42 | return f.Name(), nil |
31 | } | 43 | } |
32 | 44 | ||
33 | const httpContent = "Hello, TLS!" | 45 | func newTestServer() (*httptest.Server, *url.URL, string, error) { |
34 | |||
35 | func TestTLSBasic(t *testing.T) { | ||
36 | ts := httptest.NewTLSServer( | 46 | ts := httptest.NewTLSServer( |
37 | http.HandlerFunc( | 47 | http.HandlerFunc( |
38 | func(w http.ResponseWriter, r *http.Request) { | 48 | func(w http.ResponseWriter, r *http.Request) { |
@@ -40,18 +50,27 @@ func TestTLSBasic(t *testing.T) { | |||
40 | }, | 50 | }, |
41 | ), | 51 | ), |
42 | ) | 52 | ) |
43 | defer ts.Close() | ||
44 | 53 | ||
45 | u, err := url.Parse(ts.URL) | 54 | u, err := url.Parse(ts.URL) |
46 | if err != nil { | 55 | if err != nil { |
47 | t.Fatalf("Failed to parse URL %q: %v", ts.URL, err) | 56 | return nil, nil, "", fmt.Errorf("failed to parse URL %q: %v", ts.URL, err) |
48 | } | 57 | } |
49 | 58 | ||
50 | caFile, err := createCAFile(ts.TLS.Certificates[0].Certificate[0]) | 59 | caFile, err := createCAFile(ts.TLS.Certificates[0].Certificate[0]) |
51 | if err != nil { | 60 | if err != nil { |
52 | t.Fatalf("Failed to create CA file: %v", err) | 61 | return nil, nil, "", fmt.Errorf("failed to create CA file: %v", err) |
62 | } | ||
63 | |||
64 | return ts, u, caFile, nil | ||
65 | } | ||
66 | |||
67 | func TestTLSBasic(t *testing.T) { | ||
68 | ts, u, caFile, err := newTestServer() | ||
69 | if err != nil { | ||
70 | t.Fatalf("Failed to start test server: %v", err) | ||
53 | } | 71 | } |
54 | defer os.Remove(caFile) | 72 | defer os.Remove(caFile) |
73 | defer ts.Close() | ||
55 | 74 | ||
56 | if err := Init(); err != nil { | 75 | if err := Init(); err != nil { |
57 | t.Fatal(err) | 76 | t.Fatal(err) |
@@ -98,3 +117,130 @@ func TestTLSBasic(t *testing.T) { | |||
98 | t.Errorf("Response does not contain %q", httpContent) | 117 | t.Errorf("Response does not contain %q", httpContent) |
99 | } | 118 | } |
100 | } | 119 | } |
120 | |||
121 | func TestTLSInfo(t *testing.T) { | ||
122 | ts, u, caFile, err := newTestServer() | ||
123 | if err != nil { | ||
124 | t.Fatalf("Failed to start test server: %v", err) | ||
125 | } | ||
126 | defer os.Remove(caFile) | ||
127 | defer ts.Close() | ||
128 | |||
129 | if err := Init(); err != nil { | ||
130 | t.Fatal(err) | ||
131 | } | ||
132 | |||
133 | cfg, err := NewConfig() | ||
134 | if err != nil { | ||
135 | t.Fatal(err) | ||
136 | } | ||
137 | defer cfg.Free() | ||
138 | cfg.SetCAFile(caFile) | ||
139 | |||
140 | tls, err := NewClient(cfg) | ||
141 | if err != nil { | ||
142 | t.Fatal(err) | ||
143 | } | ||
144 | defer tls.Free() | ||
145 | |||
146 | t.Logf("Connecting to %s", u.Host) | ||
147 | |||
148 | if err := tls.Connect(u.Host, ""); err != nil { | ||
149 | t.Fatal(err) | ||
150 | } | ||
151 | defer func() { | ||
152 | if err := tls.Close(); err != nil { | ||
153 | t.Fatalf("Close failed: %v", err) | ||
154 | } | ||
155 | }() | ||
156 | |||
157 | // All of these should fail since the handshake has not completed. | ||
158 | if _, err := tls.ConnVersion(); err == nil { | ||
159 | t.Error("ConnVersion() return nil error, want error") | ||
160 | } | ||
161 | if _, err := tls.ConnCipher(); err == nil { | ||
162 | t.Error("ConnCipher() return nil error, want error") | ||
163 | } | ||
164 | |||
165 | if got, want := tls.PeerCertProvided(), false; got != want { | ||
166 | t.Errorf("PeerCertProvided() = %v, want %v", got, want) | ||
167 | } | ||
168 | for _, name := range []string{"127.0.0.1", "::1", "example.com"} { | ||
169 | if got, want := tls.PeerCertContainsName(name), false; got != want { | ||
170 | t.Errorf("PeerCertContainsName(%q) = %v, want %v", name, got, want) | ||
171 | } | ||
172 | } | ||
173 | |||
174 | if _, err := tls.PeerCertIssuer(); err == nil { | ||
175 | t.Error("PeerCertIssuer() returned nil error, want error") | ||
176 | } | ||
177 | if _, err := tls.PeerCertSubject(); err == nil { | ||
178 | t.Error("PeerCertSubject() returned nil error, want error") | ||
179 | } | ||
180 | if _, err := tls.PeerCertHash(); err == nil { | ||
181 | t.Error("PeerCertHash() returned nil error, want error") | ||
182 | } | ||
183 | if _, err := tls.PeerCertNotBefore(); err == nil { | ||
184 | t.Error("PeerCertNotBefore() returned nil error, want error") | ||
185 | } | ||
186 | if _, err := tls.PeerCertNotAfter(); err == nil { | ||
187 | t.Error("PeerCertNotAfter() returned nil error, want error") | ||
188 | } | ||
189 | |||
190 | // Complete the handshake... | ||
191 | if err := tls.Handshake(); err != nil { | ||
192 | t.Fatalf("Handshake failed: %v", err) | ||
193 | } | ||
194 | |||
195 | if version, err := tls.ConnVersion(); err != nil { | ||
196 | t.Errorf("ConnVersion() return error: %v", err) | ||
197 | } else { | ||
198 | t.Logf("Protocol version: %v", version) | ||
199 | } | ||
200 | if cipher, err := tls.ConnCipher(); err != nil { | ||
201 | t.Errorf("ConnCipher() return error: %v", err) | ||
202 | } else { | ||
203 | t.Logf("Cipher: %v", cipher) | ||
204 | } | ||
205 | |||
206 | if got, want := tls.PeerCertProvided(), true; got != want { | ||
207 | t.Errorf("PeerCertProvided() = %v, want %v", got, want) | ||
208 | } | ||
209 | for _, name := range []string{"127.0.0.1", "::1", "example.com"} { | ||
210 | if got, want := tls.PeerCertContainsName(name), true; got != want { | ||
211 | t.Errorf("PeerCertContainsName(%q) = %v, want %v", name, got, want) | ||
212 | } | ||
213 | } | ||
214 | |||
215 | if issuer, err := tls.PeerCertIssuer(); err != nil { | ||
216 | t.Errorf("PeerCertIssuer() returned error: %v", err) | ||
217 | } else { | ||
218 | t.Logf("Issuer: %v", issuer) | ||
219 | } | ||
220 | if subject, err := tls.PeerCertSubject(); err != nil { | ||
221 | t.Errorf("PeerCertSubject() returned error: %v", err) | ||
222 | } else { | ||
223 | t.Logf("Subject: %v", subject) | ||
224 | } | ||
225 | if hash, err := tls.PeerCertHash(); err != nil { | ||
226 | t.Errorf("PeerCertHash() returned error: %v", err) | ||
227 | } else if hash != certHash { | ||
228 | t.Errorf("Got cert hash %q, want %q", hash, certHash) | ||
229 | } else { | ||
230 | t.Logf("Hash: %v", hash) | ||
231 | } | ||
232 | if notBefore, err := tls.PeerCertNotBefore(); err != nil { | ||
233 | t.Errorf("PeerCertNotBefore() returned error: %v", err) | ||
234 | } else if !certNotBefore.Equal(notBefore) { | ||
235 | t.Errorf("Got cert notBefore %v, want %v", notBefore.UTC(), certNotBefore.UTC()) | ||
236 | } else { | ||
237 | t.Logf("NotBefore: %v", notBefore.UTC()) | ||
238 | } | ||
239 | if notAfter, err := tls.PeerCertNotAfter(); err != nil { | ||
240 | t.Errorf("PeerCertNotAfter() returned error: %v", err) | ||
241 | } else if !certNotAfter.Equal(notAfter) { | ||
242 | t.Errorf("Got cert notAfter %v, want %v", notAfter.UTC(), certNotAfter.UTC()) | ||
243 | } else { | ||
244 | t.Logf("NotAfter: %v", notAfter.UTC()) | ||
245 | } | ||
246 | } | ||