reformat source code

This commit is contained in:
kakwa 2016-08-23 19:38:07 +02:00
parent 4e8693da48
commit 291f58bd7e
6 changed files with 343 additions and 362 deletions

View File

@ -1,13 +1,13 @@
typedef struct uts_config { typedef struct uts_config {
char * port; char *port;
char * listen; char *listen;
bool https; bool https;
cert https_cert; cert https_cert;
void * ts_certs; void *ts_certs;
} uts_config; } uts_config;
typedef struct cert { typedef struct cert {
char * cert_file; char *cert_file;
char * key_file; char *key_file;
} cert; } cert;

View File

@ -18,11 +18,11 @@ extern "C" {
#include <stdio.h> #include <stdio.h>
/* Typedef for prototype of handler function. */ /* Typedef for prototype of handler function. */
typedef int (*ini_handler)(void* user, const char* section, typedef int (*ini_handler)(void *user, const char *section, const char *name,
const char* name, const char* value); const char *value);
/* Typedef for prototype of fgets-style reader function. */ /* Typedef for prototype of fgets-style reader function. */
typedef char* (*ini_reader)(char* str, int num, void* stream); typedef char *(*ini_reader)(char *str, int num, void *stream);
/* Parse given INI-style file. May have [section]s, name=value pairs /* Parse given INI-style file. May have [section]s, name=value pairs
(whitespace stripped), and comments starting with ';' (semicolon). Section (whitespace stripped), and comments starting with ';' (semicolon). Section
@ -37,16 +37,16 @@ typedef char* (*ini_reader)(char* str, int num, void* stream);
stop on first error), -1 on file open error, or -2 on memory allocation stop on first error), -1 on file open error, or -2 on memory allocation
error (only when INI_USE_STACK is zero). error (only when INI_USE_STACK is zero).
*/ */
int ini_parse(const char* filename, ini_handler handler, void* user); int ini_parse(const char *filename, ini_handler handler, void *user);
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't /* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
close the file when it's finished -- the caller must do that. */ close the file when it's finished -- the caller must do that. */
int ini_parse_file(FILE* file, ini_handler handler, void* user); int ini_parse_file(FILE *file, ini_handler handler, void *user);
/* Same as ini_parse(), but takes an ini_reader function pointer instead of /* Same as ini_parse(), but takes an ini_reader function pointer instead of
filename. Used for implementing custom or string-based I/O. */ filename. Used for implementing custom or string-based I/O. */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, int ini_parse_stream(ini_reader reader, void *stream, ini_handler handler,
void* user); void *user);
/* Nonzero to allow multi-line value parsing, in the style of Python's /* Nonzero to allow multi-line value parsing, in the style of Python's
configparser. If allowed, ini_parse() will call the handler with the same configparser. If allowed, ini_parse() will call the handler with the same

View File

@ -11,71 +11,64 @@
const char *argp_program_version = UTS_VERSION; const char *argp_program_version = UTS_VERSION;
const char *argp_program_bug_address = "Pierre-Francois Carpentier <carpentier.pf@gmail.com>"; const char *argp_program_bug_address =
"Pierre-Francois Carpentier <carpentier.pf@gmail.com>";
static char doc[] = "\nUTS micro timestamp server (RFC 3161)"; static char doc[] = "\nUTS micro timestamp server (RFC 3161)";
static struct argp_option options[] = { static struct argp_option options[] = {
{"conffile", 'c', "CONFFILE", 0, "Path to configuration file"}, {"conffile", 'c', "CONFFILE", 0, "Path to configuration file"},
{"daemonize", 'd', 0, 0, "Launch as a daemon"}, {"daemonize", 'd', 0, 0, "Launch as a daemon"},
{ 0 } {0}};
};
/* A description of the arguments we accept. */ /* A description of the arguments we accept. */
static char args_doc[] = "-c CONFFILE -d"; static char args_doc[] = "-c CONFFILE -d";
struct arguments struct arguments {
{ char *args[2]; /* arg1 & arg2 */
char *args[2]; /* arg1 & arg2 */ int daemonize;
int daemonize;
char *conffile; char *conffile;
}; };
static error_t parse_opt (int key, char *arg, struct argp_state *state) static error_t parse_opt(int key, char *arg, struct argp_state *state) {
{
/* Get the input argument from argp_parse, which we /* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */ know is a pointer to our arguments structure. */
struct arguments *arguments = (struct arguments *)state->input; struct arguments *arguments = (struct arguments *)state->input;
switch (key) switch (key) {
{ case 'd':
case 'd': arguments->daemonize = 1;
arguments->daemonize = 1; break;
break; case 'c':
case 'c': arguments->conffile = arg;
arguments->conffile = arg; break;
break; default:
default: return ARGP_ERR_UNKNOWN;
return ARGP_ERR_UNKNOWN;
} }
return 0; return 0;
} }
/* Our argp parser. */ /* Our argp parser. */
static struct argp argp = { options, parse_opt, args_doc, doc }; static struct argp argp = {options, parse_opt, args_doc, doc};
int main(int argc, char **argv)
{
int main(int argc, char **argv) {
struct arguments args; struct arguments args;
args.conffile = NULL; args.conffile = NULL;
args.daemonize = 0; args.daemonize = 0;
argp_parse (&argp, argc, argv, 0, 0, &args); argp_parse(&argp, argc, argv, 0, 0, &args);
if (args.daemonize) if (args.daemonize)
skeleton_daemon(); skeleton_daemon();
while (1) while (1) {
{ // TODO: Insert daemon code here.
//TODO: Insert daemon code here.
http_server_start(); http_server_start();
syslog (LOG_NOTICE, "First daemon started."); syslog(LOG_NOTICE, "First daemon started.");
sleep (5); sleep(5);
break; break;
} }
syslog (LOG_NOTICE, "First daemon terminated."); syslog(LOG_NOTICE, "First daemon terminated.");
closelog(); closelog();
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -25,27 +25,24 @@ https://github.com/benhoyt/inih
#define MAX_NAME 50 #define MAX_NAME 50
/* Strip whitespace chars off end of given string, in place. Return s. */ /* Strip whitespace chars off end of given string, in place. Return s. */
static char* rstrip(char* s) static char *rstrip(char *s) {
{ char *p = s + strlen(s);
char* p = s + strlen(s);
while (p > s && isspace((unsigned char)(*--p))) while (p > s && isspace((unsigned char)(*--p)))
*p = '\0'; *p = '\0';
return s; return s;
} }
/* Return pointer to first non-whitespace char in given string. */ /* Return pointer to first non-whitespace char in given string. */
static char* lskip(const char* s) static char *lskip(const char *s) {
{
while (*s && isspace((unsigned char)(*s))) while (*s && isspace((unsigned char)(*s)))
s++; s++;
return (char*)s; return (char *)s;
} }
/* Return pointer to first char (of chars) or inline comment in given string, /* Return pointer to first char (of chars) or inline comment in given string,
or pointer to null at end of string if neither found. Inline comment must or pointer to null at end of string if neither found. Inline comment must
be prefixed by a whitespace character to register as a comment. */ be prefixed by a whitespace character to register as a comment. */
static char* find_chars_or_comment(const char* s, const char* chars) static char *find_chars_or_comment(const char *s, const char *chars) {
{
#if INI_ALLOW_INLINE_COMMENTS #if INI_ALLOW_INLINE_COMMENTS
int was_space = 0; int was_space = 0;
while (*s && (!chars || !strchr(chars, *s)) && while (*s && (!chars || !strchr(chars, *s)) &&
@ -58,39 +55,37 @@ static char* find_chars_or_comment(const char* s, const char* chars)
s++; s++;
} }
#endif #endif
return (char*)s; return (char *)s;
} }
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
static char* strncpy0(char* dest, const char* src, size_t size) static char *strncpy0(char *dest, const char *src, size_t size) {
{
strncpy(dest, src, size); strncpy(dest, src, size);
dest[size - 1] = '\0'; dest[size - 1] = '\0';
return dest; return dest;
} }
/* See documentation in header file. */ /* See documentation in header file. */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, int ini_parse_stream(ini_reader reader, void *stream, ini_handler handler,
void* user) void *user) {
{ /* Uses a fair bit of stack (use heap instead if you need to) */
/* Uses a fair bit of stack (use heap instead if you need to) */
#if INI_USE_STACK #if INI_USE_STACK
char line[INI_MAX_LINE]; char line[INI_MAX_LINE];
#else #else
char* line; char *line;
#endif #endif
char section[MAX_SECTION] = ""; char section[MAX_SECTION] = "";
char prev_name[MAX_NAME] = ""; char prev_name[MAX_NAME] = "";
char* start; char *start;
char* end; char *end;
char* name; char *name;
char* value; char *value;
int lineno = 0; int lineno = 0;
int error = 0; int error = 0;
#if !INI_USE_STACK #if !INI_USE_STACK
line = (char*)malloc(INI_MAX_LINE); line = (char *)malloc(INI_MAX_LINE);
if (!line) { if (!line) {
return -2; return -2;
} }
@ -103,8 +98,8 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
start = line; start = line;
#if INI_ALLOW_BOM #if INI_ALLOW_BOM
if (lineno == 1 && (unsigned char)start[0] == 0xEF && if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
(unsigned char)start[1] == 0xBB && (unsigned char)start[1] == 0xBB &&
(unsigned char)start[2] == 0xBF) { (unsigned char)start[2] == 0xBF) {
start += 3; start += 3;
} }
#endif #endif
@ -129,13 +124,11 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
*end = '\0'; *end = '\0';
strncpy0(section, start + 1, sizeof(section)); strncpy0(section, start + 1, sizeof(section));
*prev_name = '\0'; *prev_name = '\0';
} } else if (!error) {
else if (!error) {
/* No ']' found on section line */ /* No ']' found on section line */
error = lineno; error = lineno;
} }
} } else if (*start) {
else if (*start) {
/* Not a comment, must be a name[=:]value pair */ /* Not a comment, must be a name[=:]value pair */
end = find_chars_or_comment(start, "=:"); end = find_chars_or_comment(start, "=:");
if (*end == '=' || *end == ':') { if (*end == '=' || *end == ':') {
@ -153,8 +146,7 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
strncpy0(prev_name, name, sizeof(prev_name)); strncpy0(prev_name, name, sizeof(prev_name));
if (!handler(user, section, name, value) && !error) if (!handler(user, section, name, value) && !error)
error = lineno; error = lineno;
} } else if (!error) {
else if (!error) {
/* No '=' or ':' found on name[=:]value line */ /* No '=' or ':' found on name[=:]value line */
error = lineno; error = lineno;
} }
@ -174,15 +166,13 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
} }
/* See documentation in header file. */ /* See documentation in header file. */
int ini_parse_file(FILE* file, ini_handler handler, void* user) int ini_parse_file(FILE *file, ini_handler handler, void *user) {
{
return ini_parse_stream((ini_reader)fgets, file, handler, user); return ini_parse_stream((ini_reader)fgets, file, handler, user);
} }
/* See documentation in header file. */ /* See documentation in header file. */
int ini_parse(const char* filename, ini_handler handler, void* user) int ini_parse(const char *filename, ini_handler handler, void *user) {
{ FILE *file;
FILE* file;
int error; int error;
file = fopen(filename, "r"); file = fopen(filename, "r");

View File

@ -1,4 +1,4 @@
/* /*
* "This product includes software developed by the OpenSSL Project * "This product includes software developed by the OpenSSL Project
* * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*/ */
@ -19,31 +19,30 @@
#include <openssl/bn.h> #include <openssl/bn.h>
/* Name of config entry that defines the OID file. */ /* Name of config entry that defines the OID file. */
# define ENV_OID_FILE "oid_file" #define ENV_OID_FILE "oid_file"
static ASN1_OBJECT *txt2obj(const char *oid); static ASN1_OBJECT *txt2obj(const char *oid);
static CONF *load_config_file(const char *configfile); static CONF *load_config_file(const char *configfile);
/* Reply related functions. */ /* Reply related functions. */
static int reply_command(CONF *conf, char *section, char *engine, static int reply_command(CONF *conf, char *section, char *engine,
char *queryfile, char *passin, char *inkey, char *queryfile, char *passin, char *inkey,
const EVP_MD *md, char *signer, char *chain, const EVP_MD *md, char *signer, char *chain,
const char *policy, char *in, int token_in, const char *policy, char *in, int token_in, char *out,
char *out, int token_out, int text); int token_out, int text);
static TS_RESP *read_PKCS7(BIO *in_bio); static TS_RESP *read_PKCS7(BIO *in_bio);
static TS_RESP *create_response(CONF *conf, const char *section, char *engine, static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
char *queryfile, char *passin, char *queryfile, char *passin, char *inkey,
char *inkey, const EVP_MD *md, char *signer, const EVP_MD *md, char *signer, char *chain,
char *chain, const char *policy); const char *policy);
static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data); static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data);
static ASN1_INTEGER *next_serial(const char *serialfile); static ASN1_INTEGER *next_serial(const char *serialfile);
static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
# define B_FORMAT_TEXT 0x8000 #define B_FORMAT_TEXT 0x8000
# define FORMAT_UNDEF 0 #define FORMAT_UNDEF 0
# define FORMAT_TEXT (1 | B_FORMAT_TEXT) /* Generic text */ #define FORMAT_TEXT (1 | B_FORMAT_TEXT) /* Generic text */
# define FORMAT_ASN1 4 /* ASN.1/DER */ #define FORMAT_ASN1 4 /* ASN.1/DER */
/* /*
int ts_http_respond(short event, ad_conn_t *conn, void *userdata) { int ts_http_respond(short event, ad_conn_t *conn, void *userdata) {
@ -67,78 +66,77 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
} }
*/ */
// This function will be called by civetweb on every new request. // This function will be called by civetweb on every new request.
static int begin_request_handler(struct mg_connection *conn) static int begin_request_handler(struct mg_connection *conn) {
{ const struct mg_request_info *request_info = mg_get_request_info(conn);
const struct mg_request_info *request_info = mg_get_request_info(conn); char content[100];
char content[100];
// Prepare the message we're going to send // Prepare the message we're going to send
int content_length = snprintf(content, sizeof(content), int content_length = snprintf(content, sizeof(content),
"Hello from civetweb! Remote port: %d", "Hello from civetweb! Remote port: %d",
request_info->remote_port); request_info->remote_port);
// Send HTTP reply to the client // Send HTTP reply to the client
mg_printf(conn, mg_printf(conn,
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n" "Content-Type: text/plain\r\n"
"Content-Length: %d\r\n" // Always set Content-Length "Content-Length: %d\r\n" // Always set Content-Length
"\r\n" "\r\n"
"%s", "%s",
content_length, content); content_length, content);
// Returning non-zero tells civetweb that our function has replied to // Returning non-zero tells civetweb that our function has replied to
// the client, and civetweb should not send client any more data. // the client, and civetweb should not send client any more data.
return 1; return 1;
} }
int http_server_start() { int http_server_start() {
struct mg_context *ctx; struct mg_context *ctx;
struct mg_callbacks callbacks; struct mg_callbacks callbacks;
// List of options. Last element must be NULL. // List of options. Last element must be NULL.
const char *options[] = {"listening_ports", "8080", NULL}; const char *options[] = {"listening_ports", "8080", NULL};
// Prepare callbacks structure. We have only one callback, the rest are NULL. // Prepare callbacks structure. We have only one callback, the rest are
memset(&callbacks, 0, sizeof(callbacks)); // NULL.
callbacks.begin_request = begin_request_handler; memset(&callbacks, 0, sizeof(callbacks));
callbacks.begin_request = begin_request_handler;
// Start the web server. // Start the web server.
ctx = mg_start(&callbacks, NULL, options); ctx = mg_start(&callbacks, NULL, options);
// Wait until user hits "enter". Server is running in separate thread. // Wait until user hits "enter". Server is running in separate thread.
// Navigating to http://localhost:8080 will invoke begin_request_handler(). // Navigating to http://localhost:8080 will invoke begin_request_handler().
getchar(); getchar();
// Stop the server. // Stop the server.
mg_stop(ctx); mg_stop(ctx);
return 0; return 0;
} }
/* /*
* Configuration file-related function definitions. * Configuration file-related function definitions.
*/ */
static ASN1_OBJECT *txt2obj(const char *oid) static ASN1_OBJECT *txt2obj(const char *oid) {
{ ASN1_OBJECT *oid_obj = NULL;
ASN1_OBJECT *oid_obj = NULL;
if ((oid_obj = OBJ_txt2obj(oid, 0)) == NULL) if ((oid_obj = OBJ_txt2obj(oid, 0)) == NULL)
// BIO_printf(bio_err, "cannot convert %s to OID\n", oid); // BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
return oid_obj; return oid_obj;
} }
//static CONF *load_config_file(const char *configfile) // static CONF *load_config_file(const char *configfile)
//{ //{
// CONF *conf = app_load_config(configfile); // CONF *conf = app_load_config(configfile);
// //
// if (conf != NULL) { // if (conf != NULL) {
// const char *p; // const char *p;
// //
//// BIO_printf(bio_err, "Using configuration from %s\n", configfile); //// BIO_printf(bio_err, "Using configuration from %s\n",
///configfile);
// p = NCONF_get_string(conf, NULL, ENV_OID_FILE); // p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
// if (p != NULL) { // if (p != NULL) {
// BIO *oid_bio = BIO_new_file(p, "r"); // BIO *oid_bio = BIO_new_file(p, "r");
@ -161,256 +159,258 @@ static ASN1_OBJECT *txt2obj(const char *oid)
*/ */
static int reply_command(CONF *conf, char *section, char *engine, static int reply_command(CONF *conf, char *section, char *engine,
char *queryfile, char *passin, char *inkey, char *queryfile, char *passin, char *inkey,
const EVP_MD *md, char *signer, char *chain, const EVP_MD *md, char *signer, char *chain,
const char *policy, char *in, int token_in, const char *policy, char *in, int token_in, char *out,
char *out, int token_out, int text) int token_out, int text) {
{ int ret = 0;
int ret = 0; TS_RESP *response = NULL;
TS_RESP *response = NULL; BIO *in_bio = NULL;
BIO *in_bio = NULL; BIO *query_bio = NULL;
BIO *query_bio = NULL; BIO *inkey_bio = NULL;
BIO *inkey_bio = NULL; BIO *signer_bio = NULL;
BIO *signer_bio = NULL; BIO *out_bio = NULL;
BIO *out_bio = NULL;
BIO *bio_err; BIO *bio_err;
if (in != NULL) { if (in != NULL) {
if ((in_bio = BIO_new_file(in, "rb")) == NULL) if ((in_bio = BIO_new_file(in, "rb")) == NULL)
goto end; goto end;
if (token_in) { if (token_in) {
response = read_PKCS7(in_bio); response = read_PKCS7(in_bio);
} else { } else {
response = d2i_TS_RESP_bio(in_bio, NULL); response = d2i_TS_RESP_bio(in_bio, NULL);
} }
} else { } else {
response = create_response(conf, section, engine, queryfile, response = create_response(conf, section, engine, queryfile, passin,
passin, inkey, md, signer, chain, policy); inkey, md, signer, chain, policy);
// if (response) // if (response)
// BIO_printf(bio_err, "Response has been generated.\n"); // BIO_printf(bio_err, "Response has been
// else //generated.\n");
// BIO_printf(bio_err, "Response is not generated.\n"); // else
} // BIO_printf(bio_err, "Response is not
if (response == NULL) //generated.\n");
goto end; }
if (response == NULL)
goto end;
/* Write response. */ /* Write response. */
if (text) { if (text) {
// if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL) // if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) ==
// goto end; //NULL)
if (token_out) { // goto end;
TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); if (token_out) {
if (!TS_TST_INFO_print_bio(out_bio, tst_info)) TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
goto end; if (!TS_TST_INFO_print_bio(out_bio, tst_info))
} else { goto end;
if (!TS_RESP_print_bio(out_bio, response)) } else {
goto end; if (!TS_RESP_print_bio(out_bio, response))
} goto end;
} else { }
// if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL) } else {
// goto end; // if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) ==
if (token_out) { //NULL)
PKCS7 *token = TS_RESP_get_token(response); // goto end;
if (!i2d_PKCS7_bio(out_bio, token)) if (token_out) {
goto end; PKCS7 *token = TS_RESP_get_token(response);
} else { if (!i2d_PKCS7_bio(out_bio, token))
if (!i2d_TS_RESP_bio(out_bio, response)) goto end;
goto end; } else {
} if (!i2d_TS_RESP_bio(out_bio, response))
} goto end;
}
}
ret = 1; ret = 1;
end: end:
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
BIO_free_all(in_bio); BIO_free_all(in_bio);
BIO_free_all(query_bio); BIO_free_all(query_bio);
BIO_free_all(inkey_bio); BIO_free_all(inkey_bio);
BIO_free_all(signer_bio); BIO_free_all(signer_bio);
BIO_free_all(out_bio); BIO_free_all(out_bio);
TS_RESP_free(response); TS_RESP_free(response);
return ret; return ret;
} }
/* Reads a PKCS7 token and adds default 'granted' status info to it. */ /* Reads a PKCS7 token and adds default 'granted' status info to it. */
static TS_RESP *read_PKCS7(BIO *in_bio) static TS_RESP *read_PKCS7(BIO *in_bio) {
{ int ret = 0;
int ret = 0; PKCS7 *token = NULL;
PKCS7 *token = NULL; TS_TST_INFO *tst_info = NULL;
TS_TST_INFO *tst_info = NULL; TS_RESP *resp = NULL;
TS_RESP *resp = NULL; TS_STATUS_INFO *si = NULL;
TS_STATUS_INFO *si = NULL;
if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL) if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
goto end; goto end;
if ((tst_info = PKCS7_to_TS_TST_INFO(token)) == NULL) if ((tst_info = PKCS7_to_TS_TST_INFO(token)) == NULL)
goto end; goto end;
if ((resp = TS_RESP_new()) == NULL) if ((resp = TS_RESP_new()) == NULL)
goto end; goto end;
if ((si = TS_STATUS_INFO_new()) == NULL) if ((si = TS_STATUS_INFO_new()) == NULL)
goto end; goto end;
// if (!TS_STATUS_INFO_set_status(si, TS_STATUS_GRANTED)) // if (!TS_STATUS_INFO_set_status(si, TS_STATUS_GRANTED))
// goto end; // goto end;
if (!TS_RESP_set_status_info(resp, si)) if (!TS_RESP_set_status_info(resp, si))
goto end; goto end;
TS_RESP_set_tst_info(resp, token, tst_info); TS_RESP_set_tst_info(resp, token, tst_info);
token = NULL; /* Ownership is lost. */ token = NULL; /* Ownership is lost. */
tst_info = NULL; /* Ownership is lost. */ tst_info = NULL; /* Ownership is lost. */
ret = 1; ret = 1;
end: end:
PKCS7_free(token); PKCS7_free(token);
TS_TST_INFO_free(tst_info); TS_TST_INFO_free(tst_info);
if (!ret) { if (!ret) {
TS_RESP_free(resp); TS_RESP_free(resp);
resp = NULL; resp = NULL;
} }
TS_STATUS_INFO_free(si); TS_STATUS_INFO_free(si);
return resp; return resp;
} }
static TS_RESP *create_response(CONF *conf, const char *section, char *engine, static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
char *queryfile, char *passin, char *queryfile, char *passin, char *inkey,
char *inkey, const EVP_MD *md, char *signer, const EVP_MD *md, char *signer, char *chain,
char *chain, const char *policy) const char *policy) {
{ int ret = 0;
int ret = 0; TS_RESP *response = NULL;
TS_RESP *response = NULL; BIO *query_bio = NULL;
BIO *query_bio = NULL; TS_RESP_CTX *resp_ctx = NULL;
TS_RESP_CTX *resp_ctx = NULL;
if ((query_bio = BIO_new_file(queryfile, "rb")) == NULL) if ((query_bio = BIO_new_file(queryfile, "rb")) == NULL)
goto end; goto end;
if ((section = TS_CONF_get_tsa_section(conf, section)) == NULL) if ((section = TS_CONF_get_tsa_section(conf, section)) == NULL)
goto end; goto end;
if ((resp_ctx = TS_RESP_CTX_new()) == NULL) if ((resp_ctx = TS_RESP_CTX_new()) == NULL)
goto end; goto end;
if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
goto end; goto end;
# ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
if (!TS_CONF_set_crypto_device(conf, section, engine)) if (!TS_CONF_set_crypto_device(conf, section, engine))
goto end; goto end;
# endif #endif
if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx)) if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
goto end; goto end;
// if (md) { // if (md) {
// if (!TS_RESP_CTX_set_signer_digest(resp_ctx, md)) // if (!TS_RESP_CTX_set_signer_digest(resp_ctx, md))
// goto end; // goto end;
// } else if (!TS_CONF_set_signer_digest(conf, section, NULL, resp_ctx)) { // } else if (!TS_CONF_set_signer_digest(conf, section, NULL, resp_ctx)) {
// goto end; // goto end;
// } // }
if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_policies(conf, section, resp_ctx)) if (!TS_CONF_set_policies(conf, section, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_digests(conf, section, resp_ctx)) if (!TS_CONF_set_digests(conf, section, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) if (!TS_CONF_set_accuracy(conf, section, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx)) if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_ordering(conf, section, resp_ctx)) if (!TS_CONF_set_ordering(conf, section, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) if (!TS_CONF_set_tsa_name(conf, section, resp_ctx))
goto end; goto end;
if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx))
goto end; goto end;
if ((response = TS_RESP_create_response(resp_ctx, query_bio)) == NULL) if ((response = TS_RESP_create_response(resp_ctx, query_bio)) == NULL)
goto end; goto end;
ret = 1; ret = 1;
end: end:
if (!ret) { if (!ret) {
TS_RESP_free(response); TS_RESP_free(response);
response = NULL; response = NULL;
} }
TS_RESP_CTX_free(resp_ctx); TS_RESP_CTX_free(resp_ctx);
BIO_free_all(query_bio); BIO_free_all(query_bio);
return response; return response;
} }
static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data) static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data) {
{ const char *serial_file = (const char *)data;
const char *serial_file = (const char *)data; ASN1_INTEGER *serial = next_serial(serial_file);
ASN1_INTEGER *serial = next_serial(serial_file);
if (!serial) { if (!serial) {
TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
"Error during serial number " "Error during serial number "
"generation."); "generation.");
TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE);
} else } else
save_ts_serial(serial_file, serial); save_ts_serial(serial_file, serial);
return serial; return serial;
} }
static ASN1_INTEGER *next_serial(const char *serialfile) static ASN1_INTEGER *next_serial(const char *serialfile) {
{ int ret = 0;
int ret = 0; BIO *in = NULL;
BIO *in = NULL; ASN1_INTEGER *serial = NULL;
ASN1_INTEGER *serial = NULL; BIGNUM *bn = NULL;
BIGNUM *bn = NULL;
if ((serial = ASN1_INTEGER_new()) == NULL) if ((serial = ASN1_INTEGER_new()) == NULL)
goto err; goto err;
if ((in = BIO_new_file(serialfile, "r")) == NULL) { if ((in = BIO_new_file(serialfile, "r")) == NULL) {
ERR_clear_error(); ERR_clear_error();
// BIO_printf(bio_err, "Warning: could not open file %s for " // BIO_printf(bio_err, "Warning: could not open file %s for
// "reading, using serial number: 1\n", serialfile); //"
if (!ASN1_INTEGER_set(serial, 1)) // "reading, using serial number: 1\n",
goto err; //serialfile);
} else { if (!ASN1_INTEGER_set(serial, 1))
char buf[1024]; goto err;
if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) { } else {
// BIO_printf(bio_err, "unable to load number from %s\n", char buf[1024];
// serialfile); if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) {
goto err; // BIO_printf(bio_err, "unable to load number from
} //%s\n",
if ((bn = ASN1_INTEGER_to_BN(serial, NULL)) == NULL) // serialfile);
goto err; goto err;
ASN1_INTEGER_free(serial); }
serial = NULL; if ((bn = ASN1_INTEGER_to_BN(serial, NULL)) == NULL)
if (!BN_add_word(bn, 1)) goto err;
goto err; ASN1_INTEGER_free(serial);
if ((serial = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) serial = NULL;
goto err; if (!BN_add_word(bn, 1))
} goto err;
ret = 1; if ((serial = BN_to_ASN1_INTEGER(bn, NULL)) == NULL)
goto err;
}
ret = 1;
err: err:
if (!ret) { if (!ret) {
ASN1_INTEGER_free(serial); ASN1_INTEGER_free(serial);
serial = NULL; serial = NULL;
} }
BIO_free_all(in); BIO_free_all(in);
BN_free(bn); BN_free(bn);
return serial; return serial;
} }
static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) {
{ int ret = 0;
int ret = 0; BIO *out = NULL;
BIO *out = NULL;
if ((out = BIO_new_file(serialfile, "w")) == NULL) if ((out = BIO_new_file(serialfile, "w")) == NULL)
goto err; goto err;
if (i2a_ASN1_INTEGER(out, serial) <= 0) if (i2a_ASN1_INTEGER(out, serial) <= 0)
goto err; goto err;
if (BIO_puts(out, "\n") <= 0) if (BIO_puts(out, "\n") <= 0)
goto err; goto err;
ret = 1; ret = 1;
err: err:
if (!ret) if (!ret)
// BIO_printf(bio_err, "could not save serial number to %s\n", // BIO_printf(bio_err, "could not save serial number to
// serialfile); //%s\n",
BIO_free_all(out); // serialfile);
return ret; BIO_free_all(out);
return ret;
} }

View File

@ -7,8 +7,7 @@
#include <syslog.h> #include <syslog.h>
#include "utils.h" #include "utils.h"
void skeleton_daemon() void skeleton_daemon() {
{
pid_t pid; pid_t pid;
/* Fork off the parent process */ /* Fork off the parent process */
@ -27,7 +26,7 @@ void skeleton_daemon()
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
/* Catch, ignore and handle signals */ /* Catch, ignore and handle signals */
//TODO: Implement a working signal handler */ // TODO: Implement a working signal handler */
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
@ -51,11 +50,10 @@ void skeleton_daemon()
/* Close all open file descriptors */ /* Close all open file descriptors */
int x; int x;
for (x = sysconf(_SC_OPEN_MAX); x>0; x--) for (x = sysconf(_SC_OPEN_MAX); x > 0; x--) {
{ close(x);
close (x);
} }
/* Open the log file */ /* Open the log file */
openlog ("firstdaemon", LOG_PID, LOG_DAEMON); openlog("firstdaemon", LOG_PID, LOG_DAEMON);
} }