|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Some openca-ocspd patches.Greetings OpenCA developers!
We have recently been looking into utilizing the OpenCA ocsp daemon for our own CA and have found it most useful. We did run into some issues with both bugs and features. After running the daemon under a small bit of load we found that the daemon would crash at random intervals - after a quick glance at the source it seems that OpenSSL was not being initialized in a thread safe manner. This fix is included within the patch. We also needed the ability for the code to handle GET style methods for ocsp requests. After looking over the current http handling code it was determined that cleaning up and re-factoring the http processing functionality may be in order. This was also included within the patch. In order to facilitate the GET requests I had to add a new flag "-u" where an administrator can specify the root URI (e.g., -u /ocsp/) so the code knows to read the encoded data found afterwards. I hope that you find these changes useful, and I thank you for the great project! ~Mark diff -Naur ../openca-ocspd-1.5.1-rc1/src/Makefile.in ./src/Makefile.in --- ../openca-ocspd-1.5.1-rc1/src/Makefile.in 2006-10-14 10:34:53.000000000 -0400 +++ ./src/Makefile.in 2009-06-05 16:03:44.000000000 -0400 @@ -63,9 +63,9 @@ configuration.c configuration.h crl.h crl.c support.c \ support.h crypto.c crypto.h http_client.c http_client.h core.h \ threads.h sock.h structs.h core.c sock.c threads.c ocsp_db.h \ - hash-db.c ocspd_engine.c ocspd_engine.h + hash-db.c ocspd_engine.c ocspd_engine.h ocsp_http.c ocsp_http.h @HAVE_ENGINE_TRUE@am__objects_1 = ocspd_engine.$(OBJEXT) -am_ocspd_OBJECTS = ocspd.$(OBJEXT) ocsp_response.$(OBJEXT) \ +am_ocspd_OBJECTS = ocspd.$(OBJEXT) ocsp_http.$(OBJEXT) ocsp_response.$(OBJEXT) \ ocsp_request.$(OBJEXT) configuration.$(OBJEXT) crl.$(OBJEXT) \ support.$(OBJEXT) crypto.$(OBJEXT) http_client.$(OBJEXT) \ core.$(OBJEXT) sock.$(OBJEXT) threads.$(OBJEXT) \ @@ -288,6 +288,7 @@ # ocspd_SOURCES = \ ocspd.c ocspd.h general.h ocsp_codes.h \ + ocsp_http.c ocsp_http.h \ ocsp_response.c ocsp_response.h \ ocsp_request.c ocsp_request.h \ configuration.c configuration.h \ @@ -402,6 +403,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash-db.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_request.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_http.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_response.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocspd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocspd_engine.Po@am__quote@ diff -Naur ../openca-ocspd-1.5.1-rc1/src/core.c ./src/core.c --- ../openca-ocspd-1.5.1-rc1/src/core.c 2006-10-21 10:50:32.000000000 -0400 +++ ./src/core.c 2009-06-05 16:03:44.000000000 -0400 @@ -13,10 +13,20 @@ extern OCSPD_CONFIG *ocspd_conf; pthread_mutex_t crl_lock = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t clifd_cond; +pthread_mutex_t *thread_locks; + +unsigned long openssl_thread_id() { + return (unsigned long) pthread_self(); +} +void openssl_thread_lock( int mode, int lock_id, const char* file, int line ) { + if ( mode & CRYPTO_LOCK ) + pthread_mutex_lock( &thread_locks[lock_id] ); + else + pthread_mutex_unlock( &thread_locks[lock_id] ); +} int start_threaded_server ( char * bind_s, char * port_s, int nthreads, OCSPD_CONFIG * ocspd_conf ) { @@ -77,6 +87,23 @@ ocspd_conf->iget = ocspd_conf->iput = 0; + int num_thread_locks = CRYPTO_num_locks(); + thread_locks = calloc( sizeof( pthread_mutex_t ), + num_thread_locks ); + + for (i = 0; i < num_thread_locks; i++) + { + if ( pthread_mutex_init( &thread_locks[i], NULL ) ) + { + fprintf(stderr, "Unable to create mutex\n"); + exit(80); + } + } + + CRYPTO_set_locking_callback( &openssl_thread_lock ); + CRYPTO_set_id_callback( &openssl_thread_id ); + + for( i = 0; i < ocspd_conf->nthreads; i++ ) { if(thread_make(i) != 0 ) { syslog(LOG_ERR, @@ -86,6 +113,7 @@ } } + /* Register the alarm handler */ set_alrm_handler(); @@ -178,6 +206,8 @@ return 1; } + + void handle_sighup ( int i ) { syslog( LOG_ERR, diff -Naur ../openca-ocspd-1.5.1-rc1/src/general.h ./src/general.h --- ../openca-ocspd-1.5.1-rc1/src/general.h 2006-10-21 08:53:55.000000000 -0400 +++ ./src/general.h 2009-06-05 16:03:44.000000000 -0400 @@ -381,6 +381,7 @@ STACK *pre_cmds; STACK *post_cmds; #endif + char *base_uri; } OCSPD_CONFIG; #define CRL_REASON_UNSPECIFIED 0 diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocsp_http.c ./src/ocsp_http.c --- ../openca-ocspd-1.5.1-rc1/src/ocsp_http.c 1969-12-31 19:00:00.000000000 -0500 +++ ./src/ocsp_http.c 2009-06-08 12:13:43.000000000 -0400 @@ -0,0 +1,573 @@ +#include <strings.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> + +#include "core.h" +#include "threads.h" +#include "sock.h" + +#include "ocsp_request.h" +#include "ocsp_http.h" + +extern OCSPD_CONFIG *ocspd_conf; + +http_method_t +decode_http_method(const char *str, int len, int *error) +{ + http_method_t method; + + switch (*str) { + case 'p': + case 'P': + if (len < 5) { + *error = HTTP_HEADER_TRUNCATED; + return METHOD_ERROR; + } + + if (strncasecmp(str, "POST ", 5)) { + *error = HTTP_INVALID_METHOD; + return METHOD_ERROR; + } + + method = METHOD_POST; + break; + case 'g': + case 'G': + if (len < 4) { + *error = HTTP_HEADER_TRUNCATED; + return METHOD_ERROR; + } + + if (strncasecmp(str, "GET ", 4)) { + *error = HTTP_INVALID_METHOD; + return METHOD_ERROR; + } + + method = METHOD_GET; + break; + default: + *error = HTTP_INVALID_METHOD; + return METHOD_ERROR; + } + + return method; +} + +char * +http_expand_hex(const char *hexstr) +{ + switch (strtol(hexstr, NULL, 16)) { + case 0x24: + return "$"; + case 0x26: + return "&"; + case 0x2B: + return "+"; + case 0x2C: + return ","; + case 0x2F: + return "/"; + case 0x3A: + return ":"; + case 0x3B: + return ";"; + case 0x3D: + return "="; + case 0x3F: + return "?"; + case 0x40: + return "@"; + case 0x20: + return " "; + case 0x22: + return "\""; + case 0x3C: + return "<"; + case 0x3E: + return ">"; + case 0x23: + return "#"; + case 0x25: + return "%"; + case 0x7b: + return "{"; + case 0x7d: + return "}"; + case 0x7c: + return "|"; + case 0x5c: + return "\\"; + case 0x5e: + return "^"; + case 0x7e: + return "~"; + case 0x5B: + return "["; + case 0x5D: + return "]"; + case 0x60: + return "`"; + default: + return NULL; + } + return NULL; +} + +char * +http_decode_base64(char *input, int len, int *tlen) +{ + BIO *bio, + *b64; + char *outbuf; + int inlen; + + if (!(outbuf = malloc(4096))) { + *tlen = -1; + return NULL; + } + + memset(outbuf, 0, 4096); + + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new_mem_buf(input, len); + bio = BIO_push(b64, bio); + + while ((inlen = BIO_read(bio, outbuf, 4096)) > 0) + *tlen += inlen; + + BIO_free_all(bio); + + return outbuf; +} + +char * +decode_uri(char *in_uri, int len) +{ + int i; + int current_byte; + int characters_written; + int outstring_len; + char *outstring; + + if (!in_uri || len <= 0) + return NULL; + + /* + * (len / 64) is the number of newline characters that will need to + * be added. + * + * We also add 2 more bytes to the end for the last \n, and a \0 + * terminator. + */ + + outstring_len = (len / 64) + len + 2; + characters_written = 0; + + if (!(outstring = malloc(outstring_len))) + return NULL; + + memset(outstring, 0, outstring_len); + + current_byte = 0; + + for (i = 0; i < len; i++) { + char *data; + char *hexstr; + char *expanded; + + data = &in_uri[i]; + + /* + * openssl base64 decoding requires our encoded string to include + * newlines after every 64 bytes + */ + if (i > 0 && !(characters_written % 63)) { + outstring[current_byte++] = '\n'; + } + + if (*data != '%') { + outstring[current_byte++] = *data; + characters_written++; + continue; + } + + if (i + 2 >= outstring_len) { + /* + * we can't actually fit a hex set here + */ + outstring[current_byte++] = *data; + characters_written++; + continue; + } + + hexstr = malloc(3); + hexstr[0] = data[1]; + hexstr[1] = data[2]; + hexstr[2] = '\0'; + + expanded = http_expand_hex(hexstr); + + if (expanded) { + outstring[current_byte++] = *expanded; + i += 2; + } else + outstring[current_byte++] = *data; + + characters_written++; + free(hexstr); + } + + outstring[current_byte] = '\n'; + + return outstring; +} + +http_rec_t * +create_http_rec(void) +{ + http_rec_t *rec; + + if (!(rec = malloc(sizeof(http_rec_t)))) + return NULL; + + memset(rec, 0, sizeof(http_rec_t)); + return rec; +} + +void +free_http_rec(http_rec_t * rec) +{ + if (!rec) + return; + + if (rec->http_raw_rec) + free(rec->http_raw_rec); + + if (rec->http_data) + free(rec->http_data); + + free(rec); +} + +int +decode_http_content_len(char *input_buf, int input_len) +{ + /* + * return values: -1 error occurred 0 not enough data >0 the length to + * read + */ + char *content_sz_raw; + char *content_sz_val_raw; + char *content_sz_val; + char *content_sz_end; + int content_sz_val_len; + int content_len; + + /* + * first find the content-length header + */ + content_sz_raw = strstr(input_buf, "Content-Length: "); + + if (!content_sz_raw) + return 0; + + /* + * paranoid overflow check + */ + if (content_sz_raw > (char *) (input_buf + input_len)) + return 0; + + content_sz_val_raw = &content_sz_raw[16]; + + if (!content_sz_val_raw) + return 0; + + if (content_sz_val_raw > (char *) (input_buf + input_len)) + return 0; + + /* + * find the end of the content-length line + */ + content_sz_end = strstr(content_sz_val_raw, "\r\n"); + + if (!content_sz_end) + return 0; + + /* + * get a general number of bytes to alloc + */ + content_sz_val_len = content_sz_end - content_sz_val_raw; + + if (content_sz_val_len <= 0) + return -1; + + if (!(content_sz_val = malloc(content_sz_val_len))) + return -1; + + memset(content_sz_val, 0, content_sz_val_len + 1); + strncpy(content_sz_val, content_sz_val_raw, content_sz_val_len); + + content_len = atoi(content_sz_val); + + free(content_sz_val); + + if (content_len >= INT_LEAST32_MAX) + return -1; + + return content_len; +} + +char * +decode_http_post_data(char *input_buf, int input_len, + int content_len, int *error) +{ + char *headers_end; + char *payload_start; + char *input_buf_end; + int current_content_len; + + + input_buf_end = (char *) (input_buf + input_len); + + /* + * find the end of all the headers + */ + headers_end = strstr(input_buf, "\r\n\r\n"); + + if (!headers_end) + headers_end = strstr(input_buf, "\n\n"); + + if (!headers_end) { + /* + * not enough data? continue on + */ + *error = HTTP_CONTINUE; + return NULL; + } + + payload_start = headers_end; + + while ((*payload_start == '\n') || (*payload_start == '\r')) { + if (payload_start > input_buf_end) + break; + + payload_start++; + } + + if (payload_start > input_buf_end) { + *error = HTTP_OVERFLOW; + return NULL; + } + + /* + * check to see if we have the entire payload as determined by the + * content_len + */ + current_content_len = input_buf_end - payload_start; + + if (current_content_len < content_len) { + *error = HTTP_CONTINUE; + return NULL; + } + + if (current_content_len > content_len) { + *error = HTTP_OVERFLOW; + return NULL; + } + + return payload_start; +} + + +http_rec_t * +decode_http_post(char *input_buf, int input_len, int *error) +{ + int content_len; + char *post_data; + http_rec_t *rec; + + content_len = decode_http_content_len(input_buf, input_len); + + if (content_len == 0) { + *error = HTTP_CONTINUE; + return NULL; + } + + if (content_len < 0) { + *error = HTTP_INVALID_CONTENTLEN; + return NULL; + } + + post_data = decode_http_post_data(input_buf, + input_len, content_len, error); + + if (!post_data) + return NULL; + + if (!(rec = create_http_rec())) { + *error = HTTP_ALLOC_ERROR; + return NULL; + } + + rec->method = METHOD_POST; + rec->request_len = input_len; + rec->content_len = content_len; + + rec->http_raw_rec = malloc(input_len); + memcpy(rec->http_raw_rec, input_buf, input_len); + + rec->http_data = malloc(content_len); + memcpy(rec->http_data, post_data, content_len); + + return rec; +} + +http_rec_t * +decode_http_get(char *input_buf, int input_len, int *error) +{ + /* + * decoding a ocsp GET request is a trivial task. Simply read the + * URI, hop past the base_uri, swap reserved characters with the real + * values, and base64 decode the string + */ + http_rec_t *rec; + char *uri_start; + char *uri_end; + char *uri; + char *decoded_uri; + char *unbased_uri; + int uri_len; + int tlen; + + rec = NULL; + tlen = 0; + + /* + * lets first find the base URI + */ + uri_start = strstr(input_buf, ocspd_conf->base_uri); + + if (!uri_start) { + *error = HTTP_BASEURI_ERROR; + return NULL; + } + + if (uri_start > (input_buf + input_len)) { + *error = HTTP_OVERFLOW; + return NULL; + } + + /* + * increment past the base_uri + */ + uri_start += strlen(ocspd_conf->base_uri); + + /* + * find the end of the GET request by looking for the protocol + */ + uri_end = strstr(uri_start, " HTTP/1"); + + if (!uri_end) { + *error = HTTP_HEADER_TRUNCATED; + return NULL; + } + + if (uri_end > (input_buf + input_len)) { + *error = HTTP_OVERFLOW; + return NULL; + } + + uri_len = uri_end - uri_start; + + if (!(uri = malloc(uri_len + 1))) { + *error = HTTP_ALLOC_ERROR; + return NULL; + } + + memset(uri, 0, uri_len + 1); + memcpy(uri, uri_start, uri_len); + + /* + * do our reserved hex encoded swapping with the real thing + */ + decoded_uri = decode_uri(uri, uri_len); + free(uri); + + if (!decoded_uri) { + *error = HTTP_URI_DECODE; + return NULL; + } + + /* + * now take the input uri and base64 decode + */ + unbased_uri = http_decode_base64(decoded_uri, + strlen(decoded_uri), &tlen); + + if (!unbased_uri || tlen <= 0) { + *error = HTTP_BASE64_DECODE; + +#if 0 + printf("DECODED %p tlen %d\n", unbased_uri, tlen); + + printf("IN BASE64\n=================\n%s\n=================\n", + decoded_uri); +#endif + + if (unbased_uri) + free(unbased_uri); + + if (decoded_uri) + free(decoded_uri); + + return NULL; + } + + if (!(rec = create_http_rec())) { + if (decoded_uri) + free(decoded_uri); + + if (unbased_uri) + free(unbased_uri); + + *error = HTTP_HEADER_TRUNCATED; + return NULL; + } + + rec->method = METHOD_GET; + rec->request_len = input_len; + rec->content_len = tlen; + rec->http_raw_rec = strdup(input_buf); + rec->http_data = unbased_uri; + + if (decoded_uri) + free(decoded_uri); + + return rec; +} + +http_rec_t * +decode_http_request(char *input_buf, int input_len, int *error) +{ + http_method_t method; + http_rec_t *rec; + + rec = NULL; + + method = decode_http_method(input_buf, input_len, error); + + switch (method) { + case METHOD_POST: + rec = decode_http_post(input_buf, input_len, error); + break; + case METHOD_GET: + rec = decode_http_get(input_buf, input_len, error); + break; + default: + return NULL; + } + + return rec; +} diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocsp_http.h ./src/ocsp_http.h --- ../openca-ocspd-1.5.1-rc1/src/ocsp_http.h 1969-12-31 19:00:00.000000000 -0500 +++ ./src/ocsp_http.h 2009-06-05 16:03:44.000000000 -0400 @@ -0,0 +1,40 @@ +#ifndef __OCSP_HTTP_H +#define __OCSP_HTTP_H + +#define HTTP_CONTINUE 0 +#define HTTP_HEADER_TRUNCATED -1 +#define HTTP_OVERFLOW -2 +#define HTTP_INVALID_CONTENTLEN -3 +#define HTTP_ALLOC_ERROR -4 +#define HTTP_BASEURI_ERROR -5 +#define HTTP_URI_DECODE -6 +#define HTTP_BASE64_DECODE -7 +#define HTTP_INVALID_METHOD -8 + +typedef enum http_method { + METHOD_POST, + METHOD_GET, + METHOD_ERROR +} http_method_t; + +typedef struct http_rec { + http_method_t method; + int request_len; + int content_len; + + char *http_raw_rec; + char *http_data; +} http_rec_t; + +http_method_t decode_http_method(const char *, int, int *); +char *http_expand_hex(const char *); +char *http_decode_base64(char *input, int len, int *tlen); +char *http_decode_uri(char *in_uri, int len); +http_rec_t *create_http_rec(void); +void free_http_rec(http_rec_t *rec); +int decode_http_content_len(char *input_buf, int input_len); +char *decode_http_post_data(char *input_buf, int input_len, int content_len, int *error); +http_rec_t *decode_http_post (char *input_buf, int input_len, int *error); +http_rec_t *decode_http_get (char *input_buf, int input_len, int *error); +http_rec_t *decode_http_request(char *input_buf, int input_len, int *error); +#endif diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocsp_request.c ./src/ocsp_request.c --- ../openca-ocspd-1.5.1-rc1/src/ocsp_request.c 2006-10-21 12:39:24.000000000 -0400 +++ ./src/ocsp_request.c 2009-06-05 16:03:44.000000000 -0400 @@ -8,6 +8,7 @@ #include "threads.h" #include "sock.h" +#include "ocsp_http.h" #include "ocsp_request.h" #define OCSPD_DEF_MAX_SIZE 65535 @@ -18,29 +19,17 @@ extern OCSPD_CONFIG *ocspd_conf; OCSP_REQUEST * ocspd_req_get_socket ( int connfd, OCSPD_CONFIG *ocspd_conf) { - ssize_t fullsize = 0; ssize_t newsize = 0; ssize_t maxsize = 0; - ssize_t cont_len = 0; - ssize_t full_req_size = 0; - char* buf = NULL; - - int post = 0; - int headers = 0; int sel_ret = 0; - int cont = 0; - - char *pnt = NULL; - char *pnt_end = NULL; - char *req_st = NULL; - BIO *mem = NULL; OCSP_REQUEST * req = NULL; - struct timeval time_out; fd_set readset; + http_rec_t *http_rec = NULL; + int error; if( !ocspd_conf ) { return (NULL); @@ -54,6 +43,8 @@ maxsize = OCSPD_DEF_MAX_SIZE - OCSPD_DEF_MAX_READ; } + error = 0; + /* Add the socket to the read set */ FD_ZERO( &readset ); FD_SET (connfd, &readset); @@ -67,14 +58,7 @@ return(NULL); } - cont = 0; - /* - while((sel_ret = Select(connfd+1, &readset, - NULL, NULL, &time_out)) >= 0) { - */ - full_req_size = 0; for(;;) { - FD_ZERO( &readset ); FD_SET (connfd, &readset); @@ -106,21 +90,15 @@ return(NULL); } - /* - if( ocspd_conf->debug ) { - syslog(LOG_ERR, "DEBUG::NETWORK::Select " - "%d (cont = %d)!", sel_ret, cont); - } - - if( ocspd_conf->debug ) { - syslog(LOG_ERR, "DEBUG::NETWORK::FD_ISSET " - "%d", FD_ISSET(connfd, &readset) ); - } - */ - - // cont += WAIT_USEC; - if (FD_ISSET (connfd, &readset)) { + if(fullsize + OCSPD_DEF_MAX_READ >= maxsize) + { + syslog(LOG_ERR, "ERROR::NET::Socket recv buffer overflow"); + + free(buf); + return NULL; + } + if((newsize = recv(connfd, &(buf[fullsize]), OCSPD_DEF_MAX_READ, 0 )) == 0 ) { break; @@ -139,106 +117,78 @@ break; } + if( ocspd_conf->debug ) { syslog(LOG_ERR, "DEBUG::NETWORK::recv " "received %d (conn = %d)!", newsize, connfd); } - - /* - if( sel_ret == 0 ) { - if( (cont/1000) >= ocspd_conf->max_timeout_secs ) { - if( ocspd_conf->verbose ) { - syslog(LOG_ERR, "ERROR::NETWORK::Timeout " - "reached while reading REQUEST (%d >= %d)!", - cont/1000, ocspd_conf->max_timeout_secs); - } - - break; - } else { - continue; - } - } - */ - - /* Check for headers */ - if( (!cont_len) && - ((pnt = strstr(buf, "Content-Length: " )) != NULL) ) { - if((pnt_end = strstr(pnt, "\r\n")) != NULL ) - sscanf((char *) (pnt+16), "%d", &cont_len ); - if(ocspd_conf->debug) { - syslog(LOG_ERR, "DEBUG::Got Content Len [%d]", - cont_len); - } - } fullsize += newsize; - if( (!headers) && - (((pnt = strstr(buf, "\r\n\r\n")) != NULL) || - ((pnt = strstr(buf, "\n\n")) != NULL)) ) { - - while( (*pnt == '\n') || (*pnt == '\r')) { - *pnt = '\x0'; - pnt++; - } - - if( !cont_len ) { - if(ocspd_conf->verbose) - syslog(LOG_ERR, "ERROR::No " - "Content-Length" - " in REQ Headers"); - if(ocspd_conf->debug) { - fprintf( stderr,"---BEGIN HEADERS---\n" - "%s\n" - "---END HEADERS---\n\n", - buf ); - } - free(buf); - return(NULL); - } - req_st = pnt; - headers = (int) (req_st - buf); - full_req_size = headers+cont_len; - } - - if( (!post) && (fullsize >= 5 ) && - ( strncmp( buf, "POST ", 5) != 0 )) { - - /* Got an error - probably not found (?) */ - if( ocspd_conf->verbose) { - syslog( LOG_ERR, "ERROR::Request::HTTP method " - "is not POST"); - } - free(buf); - return(NULL); - } - - if( fullsize >= maxsize ) { - /* Max Reading size exceeded */ - syslog( LOG_ERR, - "ERROR::Max REQUEST size exceeded [ %d ]", - maxsize ); - free( buf ); - return(NULL); - } - - if( (full_req_size > 0) && - (full_req_size - fullsize < 1 )) { - - break; + if( fullsize >= maxsize ) { + /* Max Reading size exceeded */ + syslog( LOG_ERR, + "ERROR::Max REQUEST size exceeded [ %d ]", + maxsize ); + free( buf ); + return(NULL); + } + + http_rec = decode_http_request(buf, fullsize, &error); + + if(!http_rec) + { + switch(error) + { + case HTTP_CONTINUE: + continue; + case HTTP_HEADER_TRUNCATED: + syslog(LOG_ERR, "ERROR::HTTP Header truncated"); + free(buf); + return NULL; + case HTTP_OVERFLOW: + syslog(LOG_ERR, + "ERROR::HTTP overflow detected"); + free(buf); + return NULL; + case HTTP_INVALID_CONTENTLEN: + syslog(LOG_ERR, + "ERROR::HTTP::POST Invalid Content-Length"); + free(buf); + return NULL; + case HTTP_ALLOC_ERROR: + syslog(LOG_ERR, + "CRIT::Alloc Could not allocate memory!!"); + free(buf); + return NULL; + case HTTP_BASEURI_ERROR: + syslog(LOG_ERR, + "ERROR::HTTP::GET Invalid base URI!!"); + free(buf); + return NULL; + case HTTP_URI_DECODE: + syslog(LOG_ERR, + "ERROR::HTTP::GET Could not decode the base64 encoded URI"); + free(buf); + return NULL; + case HTTP_BASE64_DECODE: + syslog(LOG_ERR, + "ERROR::HTTP::GET Could not decode base64 URI"); + free(buf); + return NULL; + case HTTP_INVALID_METHOD: + syslog(LOG_ERR, + "ERROR::HTTP Invalid method in request"); + free(buf); + return NULL; + } } + break; } } - if(ocspd_conf->debug) { - fprintf( stderr,"---BEGIN HEADERS---\n" - "%s\n" - "---END HEADERS---\n\n", - buf ); - } - - if(!(mem = BIO_new_mem_buf(req_st, cont_len) )) { + if(!(mem = BIO_new_mem_buf(http_rec->http_data, http_rec->content_len) )) { BIO *err = NULL; if((err = BIO_new(BIO_s_file())) != NULL) { @@ -247,10 +197,10 @@ BIO_free(err); } - syslog( LOG_ERR, "ERROR: Internal memory allocation error!"); + syslog(LOG_ERR, "ERROR: Internal memory allocation error!"); if(ocspd_conf->debug) { fprintf(stderr, "ERROR::req_st=%p [len %d]\n", - req_st, cont_len); + http_rec->http_data, http_rec->content_len); } } else { if((req = d2i_OCSP_REQUEST_bio(mem, NULL)) == NULL ) { @@ -260,16 +210,19 @@ fprintf(stderr, "[len %d] buf=%p -- req_st=%p " "(fullsize %d - hd_size = %d - " "rq_size = %d)\n", - cont_len, buf, - req_st, fullsize, - req_st - buf, - fullsize - (req_st - buf) ); + http_rec->content_len, buf, + http_rec->http_data, fullsize, + http_rec->http_data - buf, + fullsize - (http_rec->http_data - buf)); } } if(mem) BIO_free (mem); } - if( buf ) free (buf); + if(buf) + free (buf); + + free_http_rec(http_rec); return (req); } diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocspd.c ./src/ocspd.c --- ../openca-ocspd-1.5.1-rc1/src/ocspd.c 2006-10-21 08:58:10.000000000 -0400 +++ ./src/ocspd.c 2009-06-05 16:03:44.000000000 -0400 @@ -63,6 +63,7 @@ " -md digest - Set digest to be used [md5]\n", " -k pwd - Password protecting the private key (if any)\n", " -i passin - Passin arg\n", +" -u baseuri - Base URI for GET requests (defaults to /)\n", #ifdef _OLD_HAVE_ENGINE " -e engine - use engine e, possibly a hardware device.\n", #endif @@ -113,6 +114,7 @@ char *pidfile = NULL; char *chroot_dir = NULL; char *tmp_s = NULL; + char *base_uri = "/"; int keyform = FORMAT_PEM; /* ADD ENGINE SUPPORT */ @@ -195,6 +197,12 @@ debug=1; else if (strcmp(*argv,"-d") == 0) daemon=1; + else if (strcmp(*argv,"-u") == 0) + { + if (--argc < 1) goto bad; + base_uri = *(++argv); + } + else badops = 1; argc--; argv++; @@ -255,6 +263,9 @@ /* Set the CRL checking variables */ ocspd_conf->crl_check_validity = 0; + + /* set the base URI for GET requests */ + ocspd_conf->base_uri = base_uri; /* ENGINE support added */ #ifdef HAVE_ENGINE ------------------------------------------------------------------------------ Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects _______________________________________________ OpenCA-Devel mailing list OpenCA-Devel@... https://lists.sourceforge.net/lists/listinfo/openca-devel |
|
|
Re: Some openca-ocspd patches.Hello Mark,
thanks for the patches :D They are definitely useful.. I will integrate them soon.. I know the problem with the OpenSSL - but as we are planning on using LibPKI (that allows for direct integration with easy integration with PKCS#11 devices, among other things.. ) I was thinking about delaying the release of the new code a bit. I will probably check the patch and schedule for a new OCSP release quite soon (before porting the server under LibPKI). Thanks again :D Ciao, Max Mark Ellzey Thomas wrote: > Greetings OpenCA developers! > > We have recently been looking into utilizing the OpenCA ocsp daemon for > our own CA and have found it most useful. > > We did run into some issues with both bugs and features. > > After running the daemon under a small bit of load we found that the > daemon would crash at random intervals - after a quick glance at the > source it seems that OpenSSL was not being initialized in a thread safe > manner. This fix is included within the patch. > > We also needed the ability for the code to handle GET style methods for > ocsp requests. After looking over the current http handling code it was > determined that cleaning up and re-factoring the http processing > functionality may be in order. This was also included within the patch. > > In order to facilitate the GET requests I had to add a new flag "-u" > where an administrator can specify the root URI (e.g., -u /ocsp/) so the > code knows to read the encoded data found afterwards. > > I hope that you find these changes useful, and I thank you for the great > project! > > ~Mark ------------------------------------------------------------------------------ Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects _______________________________________________ OpenCA-Devel mailing list OpenCA-Devel@... https://lists.sourceforge.net/lists/listinfo/openca-devel |
|
|
|
|
|
Re: Some openca-ocspd patches.Hi,
I just finished "porting" the OCSP daemon to LibPKI. I have a problem with Firefox - it crashes although the responses are perfectly compliant with the RFC.. still investigating. Anyhow, I am now adding support for GET requests... work in progress... Later, Max Akbatheja@... wrote: > Max, > I tested the latest code given by Mark and it works great. Just > a FYI, Get requests are ecoded slashes for e.g.:- > > 194.186.53.31 - - [08/Jun/2009:13:41:07 -0400] "GET > /ocsp/MEUwQzBBMD8wPTAJBgUrDgMCGgUABBTlXreDlf9xPB%2F%2BlgIfsGHd3PkLhgQUYaaZbSSfDh > GI5jng%2FnTRBWlSqUMCBHAABjw%3D HTTP/1.1" 200 2389 0 "-" > "Microsoft-CryptoAPI/6.0" > > Please update the documentation to configure apache, add the following > information in httpd.conf otherwise apache webserver will get a 404 error:- > > *AllowEncodedSlashes On > ProxyRequests Off > ProxyPass /ocsp **http://localhost:2560/ocsp** nocanon > ProxyPassReverse /ocsp **http://localhost:2560/ocsp/** nocanon* > ** > Thanks > Ajay Best Regards, Massimiliano Pala --o------------------------------------------------------------------------ Massimiliano Pala [OpenCA Project Manager] openca@... project.manager@... Dartmouth Computer Science Dept Home Phone: +1 (603) 369-9332 PKI/Trust Laboratory Work Phone: +1 (603) 646-8734 --o------------------------------------------------------------------------ People who think they know everything are a great annoyance to those of us who do. -- Isaac Asimov ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ OpenCA-Devel mailing list OpenCA-Devel@... https://lists.sourceforge.net/lists/listinfo/openca-devel |
| Free embeddable forum powered by Nabble | Forum Help |