NetSurf
ssl_cert.c
Go to the documentation of this file.
1 /*
2  * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * \file
21  * Implementation of win32 certificate viewing using nsw32 core windows.
22  */
23 
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <windows.h>
27 
28 #include "utils/log.h"
29 #include "utils/nsoption.h"
30 #include "netsurf/keypress.h"
31 #include "netsurf/plotters.h"
32 #include "desktop/sslcert_viewer.h"
33 
34 #include "windows/windbg.h"
35 #include "windows/plot.h"
36 #include "windows/corewindow.h"
37 #include "windows/gui.h"
38 #include "windows/resourceid.h"
39 #include "windows/ssl_cert.h"
40 
41 /* spacing and sizes for dialog elements from
42  * https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486(v=vs.85).aspx#sizingandspacing
43  */
44 /** dialog margin */
45 #define DLG_MRGN 11
46 /** warning icon height */
47 #define WRN_ICO_H 32
48 /** comand button width */
49 #define CMD_BTN_W 75
50 /** command button height */
51 #define CMD_BTN_H 23
52 
53 static const char windowclassname_sslcert[] = "nswssslcertwindow";
54 
55 /** win32 ssl certificate view context */
58 
59  /** SSL certificate viewer context data */
61 
62  /** dialog window handle */
63  HWND hWnd;
64 
65  /** accept button handle */
66  HWND hAccept;
67 
68  /** reject button handle */
69  HWND hReject;
70 
71  /** warning text handle */
72  HWND hTxt;
73 };
74 
75 
76 /**
77  * callback for keypress on ssl certificate window
78  *
79  * \param nsw32_cw The nsw32 core window structure.
80  * \param nskey The netsurf key code
81  * \return NSERROR_OK on success otherwise appropriate error code
82  */
83 static nserror
84 nsw32_sslcert_viewer_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
85 {
86  struct nsw32_sslcert_window *crtvrfy_win;
87 
88  /* technically degenerate container of */
89  crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw;
90 
91  if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
92  return NSERROR_OK;
93  }
95 }
96 
97 
98 /**
99  * callback for mouse action on ssl certificate window
100  *
101  * \param nsw32_cw The nsw32 core window structure.
102  * \param mouse_state netsurf mouse state on event
103  * \param x location of event
104  * \param y location of event
105  * \return NSERROR_OK on success otherwise appropriate error code
106  */
107 static nserror
109  browser_mouse_state mouse_state,
110  int x, int y)
111 {
112  struct nsw32_sslcert_window *crtvrfy_win;
113 
114  /* technically degenerate container of */
115  crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw;
116 
117  sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
118 
119  return NSERROR_OK;
120 }
121 
122 
123 /**
124  * callback on draw event for ssl certificate window
125  *
126  * \param nsw32_cw The nsw32 core window structure.
127  * \param scrollx The horizontal scroll offset.
128  * \param scrolly The vertical scroll offset.
129  * \param r The rectangle of the window that needs updating.
130  * \return NSERROR_OK on success otherwise appropriate error code
131  */
132 static nserror
134  int scrollx,
135  int scrolly,
136  struct rect *r)
137 {
138  struct nsw32_sslcert_window *crtvrfy_win;
139  struct redraw_context ctx = {
140  .interactive = true,
141  .background_images = true,
142  .plot = &win_plotters
143  };
144 
145  /* technically degenerate container of */
146  crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw;
147 
148  sslcert_viewer_redraw(crtvrfy_win->ssl_data,
149  -scrollx, -scrolly,
150  r, &ctx);
151 
152  return NSERROR_OK;
153 }
154 
155 
156 /**
157  * callback on close event for ssl certificate window
158  *
159  * \param nsw32_cw The nsw32 core window structure.
160  * \return NSERROR_OK on success otherwise appropriate error code
161  */
162 static nserror
164 {
165  DestroyWindow(nsw32_cw->hWnd);
166 
167  return NSERROR_OK;
168 }
169 
170 
171 /* exported interface documented in nsw32/ssl_cert.h */
173  const struct cert_chain *chain,
174  nserror (*cb)(bool proceed, void *pw),
175  void *cbpw)
176 {
177  struct nsw32_sslcert_window *ncwin;
178  nserror res;
179 
180  ncwin = malloc(sizeof(struct nsw32_sslcert_window));
181  if (ncwin == NULL) {
182  return NSERROR_NOMEM;
183  }
184 
185  /* initialise certificate viewing interface */
186  res = sslcert_viewer_create_session_data(url, cb, cbpw, chain, &ncwin->ssl_data);
187  if (res != NSERROR_OK) {
188  free(ncwin);
189  return res;
190  }
191 
192  NSLOG(netsurf, INFO, "creating hInstance %p SSL window", hinst);
193  ncwin->hWnd = CreateWindowEx(0,
195  "SSL Certificate viewer",
196  WS_OVERLAPPEDWINDOW |
197  WS_CLIPSIBLINGS |
198  WS_CLIPCHILDREN |
199  CS_DBLCLKS,
200  CW_USEDEFAULT,
201  CW_USEDEFAULT,
202  500,
203  400,
204  NULL,
205  NULL,
206  hinst,
207  NULL);
208  if (ncwin->hWnd == NULL) {
209  NSLOG(netsurf, INFO, "Window create failed");
210  return NSERROR_NOMEM;
211  }
212 
213  ncwin->core.title = NULL;
218 
219  res = nsw32_corewindow_init(hinst, ncwin->hWnd, &ncwin->core);
220  if (res != NSERROR_OK) {
221  free(ncwin);
222  return res;
223  }
224 
225  res = sslcert_viewer_init(ncwin->core.cb_table,
226  (struct core_window *)ncwin,
227  ncwin->ssl_data);
228  if (res != NSERROR_OK) {
229  free(ncwin);
230  return res;
231  }
232 
233  ncwin->hAccept = CreateWindowEx(0,
234  "BUTTON",
235  "Accept",
236  WS_TABSTOP|WS_VISIBLE|
237  WS_CHILD|BS_DEFPUSHBUTTON,
238  CW_USEDEFAULT,
239  CW_USEDEFAULT,
240  CMD_BTN_W,
241  CMD_BTN_H,
242  ncwin->hWnd,
243  (HMENU)IDC_SSLCERT_BTN_ACCEPT,
244  hinst,
245  NULL);
246  HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);
247  SendMessage(ncwin->hAccept, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE,0));
248  ncwin->hReject = CreateWindowEx(0,
249  "BUTTON",
250  "Reject",
251  WS_TABSTOP|WS_VISIBLE|
252  WS_CHILD|BS_DEFPUSHBUTTON,
253  CW_USEDEFAULT,
254  CW_USEDEFAULT,
255  CMD_BTN_W,
256  CMD_BTN_H,
257  ncwin->hWnd,
258  (HMENU)IDC_SSLCERT_BTN_REJECT,
259  hinst,
260  NULL);
261  SendMessage(ncwin->hReject, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE,0));
262 
263  CreateWindowEx(0,
264  "STATIC",
265  IDI_WARNING,
266  WS_VISIBLE | WS_CHILD | SS_ICON,
267  DLG_MRGN,
268  DLG_MRGN,
269  CMD_BTN_W,
270  CMD_BTN_H,
271  ncwin->hWnd,
272  NULL,
273  NULL,
274  NULL);
275  ncwin->hTxt = CreateWindowEx(0,
276  "STATIC",
277  "NetSurf failed to verify the authenticity of an SSL certificate. Verify the certificate details",
278  WS_VISIBLE | WS_CHILD | SS_LEFT,
280  DLG_MRGN + 5,
281  400,
282  WRN_ICO_H - 5,
283  ncwin->hWnd,
284  NULL,
285  NULL,
286  NULL);
287  SendMessage(ncwin->hTxt, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE,0));
288 
289  SetProp(ncwin->hWnd, TEXT("CertWnd"), (HANDLE)ncwin);
290 
291  ShowWindow(ncwin->hWnd, SW_SHOWNORMAL);
292 
293  return NSERROR_OK;
294 }
295 
296 
297 /**
298  * position and size ssl cert window widgets.
299  *
300  * \param hwnd The win32 handle of the window
301  * \param certwin The certificate viewer context
302  */
303 static void
305 {
306  RECT rc;
307  GetClientRect(hwnd, &rc);
308  /* position certificate drawable */
309  MoveWindow(certwin->core.hWnd,
310  DLG_MRGN,
312  rc.right - (DLG_MRGN + DLG_MRGN),
313  rc.bottom - (DLG_MRGN + WRN_ICO_H + DLG_MRGN + DLG_MRGN + CMD_BTN_H + DLG_MRGN),
314  TRUE);
315  /* position accept button */
316  MoveWindow(certwin->hAccept,
317  rc.right - (DLG_MRGN + CMD_BTN_W),
318  rc.bottom - (DLG_MRGN + CMD_BTN_H),
319  CMD_BTN_W,
320  CMD_BTN_H,
321  TRUE);
322  /* position reject button */
323  MoveWindow(certwin->hReject,
324  rc.right - (DLG_MRGN + CMD_BTN_W + 7 + CMD_BTN_W),
325  rc.bottom - (DLG_MRGN + CMD_BTN_H),
326  CMD_BTN_W,
327  CMD_BTN_H,
328  TRUE);
329  /* position text */
330  MoveWindow(certwin->hTxt,
332  DLG_MRGN + 5,
333  rc.right - (DLG_MRGN + WRN_ICO_H + DLG_MRGN + DLG_MRGN),
334  WRN_ICO_H - 5,
335  TRUE);
336 }
337 
338 
339 /**
340  * Destroy a certificate viewing window
341  *
342  * \param crtwin The certificate viewer context
343  * \return NSERROR_OK on success otherwise appropriate error code
344  */
346 {
347  nserror res;
348 
349  res = sslcert_viewer_fini(crtwin->ssl_data);
350  if (res == NSERROR_OK) {
351  res = nsw32_corewindow_fini(&crtwin->core);
352  DestroyWindow(crtwin->hWnd);
353  free(crtwin);
354  }
355  return res;
356 }
357 
358 
359 /**
360  * handle command message on ssl certificate viewing window.
361  *
362  * \param hwnd The win32 window handle.
363  * \param crtwin certificate window context.
364  * \param notification_code notifiction code
365  * \param identifier notification identifier
366  * \param ctrl_window The win32 control window handle
367  * \return appropriate response for command
368  */
369 static LRESULT
371  struct nsw32_sslcert_window *crtwin,
372  int notification_code,
373  int identifier,
374  HWND ctrl_window)
375 {
376  NSLOG(netsurf, INFO,
377  "notification_code %x identifier %x ctrl_window %p",
378  notification_code,
379  identifier,
380  ctrl_window);
381 
382  switch(identifier) {
385  nsw32_crtvrfy_destroy(crtwin);
386  break;
387 
390  nsw32_crtvrfy_destroy(crtwin);
391  break;
392 
393  default:
394  return 1; /* unhandled */
395  }
396  return 0; /* control message handled */
397 }
398 
399 
400 /**
401  * callback for SSL certificate window win32 events
402  *
403  * \param hwnd The win32 window handle
404  * \param msg The win32 message identifier
405  * \param wparam The w win32 parameter
406  * \param lparam The l win32 parameter
407  */
408 static LRESULT CALLBACK
410  UINT msg,
411  WPARAM wparam,
412  LPARAM lparam)
413 {
414  struct nsw32_sslcert_window *crtwin;
415  crtwin = GetProp(hwnd, TEXT("CertWnd"));
416  if (crtwin != NULL) {
417  switch (msg) {
418  case WM_SIZE:
419  nsw32_window_ssl_cert_size(hwnd, crtwin);
420  break;
421 
422  case WM_COMMAND:
424  crtwin,
425  HIWORD(wparam),
426  LOWORD(wparam),
427  (HWND)lparam) == 0) {
428  return 0;
429  }
430  break;
431 
432  case WM_CLOSE:
434  nsw32_crtvrfy_destroy(crtwin);
435  return 0;
436  }
437  }
438 
439  return DefWindowProc(hwnd, msg, wparam, lparam);
440 }
441 
442 
443 /* exported interface documented in nsw32/ssl_cert.h */
445 {
446  nserror ret = NSERROR_OK;
447  WNDCLASSEX wc;
448 
449  /* drawable area */
450  wc.cbSize = sizeof(WNDCLASSEX);
451  wc.style = 0;
452  wc.lpfnWndProc = nsw32_window_ssl_cert_event_callback;
453  wc.cbClsExtra = 0;
454  wc.cbWndExtra = 0;
455  wc.hInstance = hInstance;
456  wc.hIcon = NULL;
457  wc.hCursor = NULL;
458  wc.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
459  wc.lpszMenuName = NULL;
460  wc.lpszClassName = windowclassname_sslcert;
461  wc.hIconSm = NULL;
462 
463  if (RegisterClassEx(&wc) == 0) {
464  win_perror("CertVerifyClass");
465  ret = NSERROR_INIT_FAILED;
466  }
467 
468  return ret;
469 }
HWND hAccept
accept button handle
Definition: ssl_cert.c:66
Target independent plotting interface.
nserror sslcert_viewer_create_session_data(struct nsurl *url, nserror(*cb)(bool proceed, void *pw), void *cbpw, const struct cert_chain *chain, struct sslcert_session_data **ssl_d)
Create ssl certificate viewer session data.
#define IDC_SSLCERT_BTN_REJECT
Definition: resourceid.h:95
nserror nsw32_cert_verify(struct nsurl *url, const struct cert_chain *chain, nserror(*cb)(bool proceed, void *pw), void *cbpw)
Prompt the user to verify a certificate with issuse.
Definition: ssl_cert.c:172
#define WRN_ICO_H
warning icon height
Definition: ssl_cert.c:47
win32 ssl certificate view context
Definition: ssl_cert.c:56
#define CMD_BTN_W
comand button width
Definition: ssl_cert.c:49
browser_mouse_state
Mouse state.
Definition: mouse.h:43
Functionality is not implemented.
Definition: errors.h:61
HWND hReject
reject button handle
Definition: ssl_cert.c:69
nserror sslcert_viewer_accept(struct sslcert_session_data *ssl_d)
Accept a certificate chain.
Memory exhaustion.
Definition: errors.h:32
const struct plotter_table win_plotters
win32 API plot operation table
Definition: plot.c:1040
struct sslcert_session_data * ssl_data
SSL certificate viewer context data.
Definition: ssl_cert.c:60
struct core_window_callback_table * cb_table
table of callbacks for core window operations
Definition: corewindow.h:44
#define CMD_BTN_H
command button height
Definition: ssl_cert.c:51
nserror nsws_create_cert_verify_class(HINSTANCE hInstance)
Create the ssl viewer window class.
Definition: ssl_cert.c:444
nserror(* draw)(struct nsw32_corewindow *nsw32_cw, int scrollx, int scrolly, struct rect *r)
callback to draw on drawable area of nsw32 core window
Definition: corewindow.h:53
void sslcert_viewer_redraw(struct sslcert_session_data *ssl_d, int x, int y, struct rect *clip, const struct redraw_context *ctx)
Redraw the ssl certificate viewer.
Interface to key press operations.
bool sslcert_viewer_keypress(struct sslcert_session_data *ssl_d, uint32_t key)
Key press handling.
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
Option reading and saving interface.
nserror nsw32_corewindow_init(HINSTANCE hInstance, HWND hWndParent, struct nsw32_corewindow *nsw32_cw)
initialise elements of nsw32 core window.
Definition: corewindow.c:517
nserror sslcert_viewer_init(struct core_window_callback_table *cw_t, void *core_window_handle, struct sslcert_session_data *ssl_d)
Initialise a ssl certificate viewer from session data.
nserror(* close)(struct nsw32_corewindow *nsw32_cw)
callback for window close event
Definition: corewindow.h:83
nserror
Enumeration of error codes.
Definition: errors.h:29
nserror(* key)(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
callback for keypress on nsw32 core window
Definition: corewindow.h:64
static LRESULT nsw32_window_ssl_cert_command(HWND hwnd, struct nsw32_sslcert_window *crtwin, int notification_code, int identifier, HWND ctrl_window)
handle command message on ssl certificate viewing window.
Definition: ssl_cert.c:370
nserror(* mouse)(struct nsw32_corewindow *nsw32_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse event on nsw32 core window
Definition: corewindow.h:75
HWND hWnd
dialog window handle
Definition: ssl_cert.c:63
Initialisation failed.
Definition: errors.h:38
HWND hWnd
window handle
Definition: corewindow.h:29
No error.
Definition: errors.h:30
HWND hTxt
warning text handle
Definition: ssl_cert.c:72
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
static void nsw32_window_ssl_cert_size(HWND hwnd, struct nsw32_sslcert_window *certwin)
position and size ssl cert window widgets.
Definition: ssl_cert.c:304
#define DLG_MRGN
dialog margin
Definition: ssl_cert.c:45
static nserror nsw32_sslcert_viewer_close(struct nsw32_corewindow *nsw32_cw)
callback on close event for ssl certificate window
Definition: ssl_cert.c:163
void win_perror(const char *lpszFunction)
Definition: windbg.c:633
SSL Certificate verification UI interface.
static nserror nsw32_sslcert_viewer_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
callback for keypress on ssl certificate window
Definition: ssl_cert.c:84
struct nsw32_corewindow core
Definition: ssl_cert.c:57
nserror sslcert_viewer_fini(struct sslcert_session_data *ssl_d)
Finalise a ssl certificate viewer.
X509 certificate chain.
Definition: ssl_certs.h:59
Redraw context.
Definition: plotters.h:51
#define ShowWindow(...)
Definition: os3support.h:172
static nserror nsw32_sslcert_viewer_draw(struct nsw32_corewindow *nsw32_cw, int scrollx, int scrolly, struct rect *r)
callback on draw event for ssl certificate window
Definition: ssl_cert.c:133
HINSTANCE hinst
win32 application instance handle.
Definition: gui.c:45
Rectangle coordinates.
Definition: types.h:40
static LRESULT CALLBACK nsw32_window_ssl_cert_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
callback for SSL certificate window win32 events
Definition: ssl_cert.c:409
static nserror nsw32_sslcert_viewer_mouse(struct nsw32_corewindow *nsw32_cw, browser_mouse_state mouse_state, int x, int y)
callback for mouse action on ssl certificate window
Definition: ssl_cert.c:108
#define IDC_SSLCERT_BTN_ACCEPT
Definition: resourceid.h:94
nserror sslcert_viewer_reject(struct sslcert_session_data *ssl_d)
Reject a certificate chain.
ssl certificate verification context.
nsw32 core window state
Definition: corewindow.h:27
Interface to win32 certificate viewing using nsw32 core windows.
void sslcert_viewer_mouse_action(struct sslcert_session_data *ssl_d, browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
static const char windowclassname_sslcert[]
Definition: ssl_cert.c:53
nserror nsw32_corewindow_fini(struct nsw32_corewindow *nsw32_cw)
finalise elements of nsw32 core window.
Definition: corewindow.c:576
static nserror nsw32_crtvrfy_destroy(struct nsw32_sslcert_window *crtwin)
Destroy a certificate viewing window.
Definition: ssl_cert.c:345
const char * title
window title
Definition: corewindow.h:38