netsurf/riscos/sslcert.c
John Mark Bell 8db70d8e2d UTF-8 capable single/multi-line text area/display field - needs
optimisation, completion of outstanding todos.
Use this to display SSL certificate issuer and subject information.

svn path=/trunk/netsurf/; revision=2647
2006-06-26 01:14:33 +00:00

219 lines
5.8 KiB
C

/*
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk>
*/
/** \file
* SSL Certificate verification UI (implementation)
*/
#include "netsurf/utils/config.h"
#ifdef WITH_SSL
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "oslib/wimp.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetch.h"
#include "netsurf/content/urldb.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/dialog.h"
#include "netsurf/riscos/textarea.h"
#include "netsurf/riscos/wimp_event.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"
#define ICON_CERT_VERSION 1
#define ICON_CERT_VALID_FROM 2
#define ICON_CERT_TYPE 3
#define ICON_CERT_VALID_TO 4
#define ICON_CERT_SERIAL 5
#define ICON_CERT_ISSUER 6
#define ICON_CERT_SUBJECT 7
#define ICON_CERT_REJECT 8
#define ICON_CERT_ACCEPT 9
static wimp_window *dialog_cert_template;
struct session_cert {
char version[16], valid_from[32], valid_to[32], type[8], serial[32];
char *url;
uintptr_t issuer;
uintptr_t subject;
struct browser_window *bw;
};
static void ro_gui_cert_open(struct browser_window *bw, const char *url,
const struct ssl_cert_info *certdata);
static void ro_gui_cert_close(wimp_w w);
static bool ro_gui_cert_apply(wimp_w w);
/**
* Load the cert window template
*/
void ro_gui_cert_init(void)
{
dialog_cert_template = ro_gui_dialog_load_template("sslcert");
}
/**
* Open the certificate verification dialog
*/
void gui_cert_verify(struct browser_window *bw, struct content *c,
const struct ssl_cert_info *certs, unsigned long num)
{
assert(bw && c && certs);
/** \todo Display entire certificate chain */
ro_gui_cert_open(bw, c->url, certs);
}
void ro_gui_cert_open(struct browser_window *bw, const char *url,
const struct ssl_cert_info *certdata)
{
struct session_cert *session;
wimp_w w;
os_error *error;
session = malloc(sizeof(struct session_cert));
if (!session) {
warn_user("NoMemory", 0);
return;
}
session->url = strdup(url);
if (!session->url) {
free(session);
warn_user("NoMemory", 0);
return;
}
session->bw = bw;
snprintf(session->version, sizeof session->version, "%ld",
certdata->version);
snprintf(session->valid_from, sizeof session->valid_from, "%s",
certdata->not_before);
snprintf(session->type, sizeof session->type, "%d",
certdata->cert_type);
snprintf(session->valid_to, sizeof session->valid_to, "%s",
certdata->not_after);
snprintf(session->serial, sizeof session->serial, "%ld",
certdata->serial);
dialog_cert_template->icons[ICON_CERT_VERSION].data.indirected_text.text = session->version;
dialog_cert_template->icons[ICON_CERT_VERSION].data.indirected_text.size = strlen(session->version) + 1;
dialog_cert_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.text = session->valid_from;
dialog_cert_template->icons[ICON_CERT_VALID_FROM].data.indirected_text.size = strlen(session->valid_from) + 1;
dialog_cert_template->icons[ICON_CERT_TYPE].data.indirected_text.text = session->type;
dialog_cert_template->icons[ICON_CERT_TYPE].data.indirected_text.size = strlen(session->type) + 1;
dialog_cert_template->icons[ICON_CERT_VALID_TO].data.indirected_text.text = session->valid_to;
dialog_cert_template->icons[ICON_CERT_VALID_TO].data.indirected_text.size = strlen(session->valid_to) + 1;
dialog_cert_template->icons[ICON_CERT_SERIAL].data.indirected_text.text = session->serial;
dialog_cert_template->icons[ICON_CERT_SERIAL].data.indirected_text.size = strlen(session->serial) + 1;
error = xwimp_create_window(dialog_cert_template, &w);
if (error) {
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
free(session);
warn_user("MiscError", error->errmess);
return;
}
session->issuer = textarea_create(w, ICON_CERT_ISSUER,
TEXTAREA_MULTILINE | TEXTAREA_READONLY, NULL, 0);
if (!session->issuer) {
xwimp_delete_window(w);
free(session);
warn_user("NoMemory", 0);
return;
}
if (!textarea_set_text(session->issuer, certdata->issuer)) {
textarea_destroy(session->issuer);
xwimp_delete_window(w);
free(session);
warn_user("NoMemory", 0);
return;
}
session->subject = textarea_create(w, ICON_CERT_SUBJECT,
TEXTAREA_MULTILINE | TEXTAREA_READONLY, NULL, 0);
if (!session->subject) {
textarea_destroy(session->issuer);
xwimp_delete_window(w);
free(session);
warn_user("NoMemory", 0);
return;
}
if (!textarea_set_text(session->subject, certdata->subject)) {
textarea_destroy(session->subject);
textarea_destroy(session->issuer);
xwimp_delete_window(w);
free(session);
warn_user("NoMemory", 0);
return;
}
ro_gui_wimp_event_register_cancel(w, ICON_CERT_REJECT);
ro_gui_wimp_event_register_ok(w, ICON_CERT_ACCEPT, ro_gui_cert_apply);
ro_gui_wimp_event_register_close_window(w, ro_gui_cert_close);
ro_gui_wimp_event_set_user_data(w, session);
ro_gui_dialog_open_persistent(bw->window->window, w, false);
}
/**
* Handle closing of certificate verification dialog
*/
void ro_gui_cert_close(wimp_w w)
{
os_error *error;
struct session_cert *session;
session = (struct session_cert *)ro_gui_wimp_event_get_user_data(w);
assert(session);
textarea_destroy(session->subject);
textarea_destroy(session->issuer);
free(session->url);
free(session);
ro_gui_wimp_event_finalise(w);
error = xwimp_delete_window(w);
if (error)
LOG(("xwimp_delete_window: 0x%x: %s",
error->errnum, error->errmess));
}
/**
* Handle acceptance of certificate
*/
bool ro_gui_cert_apply(wimp_w w)
{
struct session_cert *session;
session = (struct session_cert *)ro_gui_wimp_event_get_user_data(w);
assert(session);
urldb_set_cert_permissions(session->url, true);
browser_window_go(session->bw, session->url, 0, true);
return true;
}
#endif