diff options
| author | jsing <> | 2015-10-13 13:58:33 +0000 |
|---|---|---|
| committer | jsing <> | 2015-10-13 13:58:33 +0000 |
| commit | 4eaafd7b3e1eb2bc06fa36e8f69ba019d013b344 (patch) | |
| tree | ec234009d935148c3e2ccbbd60d5a54c2a29aef0 /src | |
| parent | a1763a3fd369834f4c0a9597591f4cd0c8b0a0c8 (diff) | |
| download | openbsd-4eaafd7b3e1eb2bc06fa36e8f69ba019d013b344.tar.gz openbsd-4eaafd7b3e1eb2bc06fa36e8f69ba019d013b344.tar.bz2 openbsd-4eaafd7b3e1eb2bc06fa36e8f69ba019d013b344.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 | } | ||
