added mysql source for win build
--HG-- branch : trunk
This commit is contained in:
Vendored
+2583
File diff suppressed because it is too large
Load Diff
+726
@@ -0,0 +1,726 @@
|
||||
/*
|
||||
* Analyze the profile file (cmon.out) written out by the dbug
|
||||
* routines with profiling enabled.
|
||||
*
|
||||
* Copyright June 1987, Binayak Banerjee
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program may be freely distributed under the same terms and
|
||||
* conditions as Fred Fish's Dbug package.
|
||||
*
|
||||
* Compile with -- cc -O -s -o %s analyze.c
|
||||
*
|
||||
* Analyze will read an trace file created by the dbug package
|
||||
* (when run with traceing enabled). It will then produce a
|
||||
* summary on standard output listing the name of each traced
|
||||
* function, the number of times it was called, the percentage
|
||||
* of total calls, the time spent executing the function, the
|
||||
* proportion of the total time and the 'importance'. The last
|
||||
* is a metric which is obtained by multiplying the proportions
|
||||
* of calls and the proportions of time for each function. The
|
||||
* greater the importance, the more likely it is that a speedup
|
||||
* could be obtained by reducing the time taken by that function.
|
||||
*
|
||||
* Note that the timing values that you obtain are only rough
|
||||
* measures. The overhead of the dbug package is included
|
||||
* within. However, there is no need to link in special profiled
|
||||
* libraries and the like.
|
||||
*
|
||||
* CHANGES:
|
||||
*
|
||||
* 2-Mar-89: fnf
|
||||
* Changes to support tracking of stack usage. This required
|
||||
* reordering the fields in the profile log file to make
|
||||
* parsing of different record types easier. Corresponding
|
||||
* changes made in dbug runtime library. Also used this
|
||||
* opportunity to reformat the code more to my liking (my
|
||||
* apologies to Binayak Banerjee for "uglifying" his code).
|
||||
*
|
||||
* 24-Jul-87: fnf
|
||||
* Because I tend to use functions names like
|
||||
* "ExternalFunctionDoingSomething", I've rearranged the
|
||||
* printout to put the function name last in each line, so
|
||||
* long names don't screw up the formatting unless they are
|
||||
* *very* long and wrap around the screen width...
|
||||
*
|
||||
* 24-Jul-87: fnf
|
||||
* Modified to put out table very similar to Unix profiler
|
||||
* by default, but also puts out original verbose table
|
||||
* if invoked with -v flag.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <my_pthread.h>
|
||||
|
||||
static char *my_name;
|
||||
static int verbose;
|
||||
|
||||
/*
|
||||
* Structure of the stack.
|
||||
*/
|
||||
|
||||
#define PRO_FILE "dbugmon.out" /* Default output file name */
|
||||
#define STACKSIZ 100 /* Maximum function nesting */
|
||||
#define MAXPROCS 10000 /* Maximum number of function calls */
|
||||
|
||||
# ifdef BSD
|
||||
# include <sysexits.h>
|
||||
# else
|
||||
# define EX_SOFTWARE 1
|
||||
# define EX_DATAERR 1
|
||||
# define EX_USAGE 1
|
||||
# define EX_OSERR 1
|
||||
# define EX_IOERR 1
|
||||
#ifndef EX_OK
|
||||
# define EX_OK 0
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#define __MERF_OO_ "%s: Malloc Failed in %s: %d\n"
|
||||
|
||||
#define MALLOC(Ptr,Num,Typ) do /* Malloc w/error checking & exit */ \
|
||||
if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \
|
||||
{fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
|
||||
exit(EX_OSERR);} while(0)
|
||||
|
||||
#define Malloc(Ptr,Num,Typ) do /* Weaker version of above */\
|
||||
if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \
|
||||
fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
|
||||
while(0)
|
||||
|
||||
#define FILEOPEN(Fp,Fn,Mod) do /* File open with error exit */ \
|
||||
if (!(Fp = fopen(Fn,Mod)))\
|
||||
{fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
|
||||
exit(EX_IOERR);} while(0)
|
||||
|
||||
#define Fileopen(Fp,Fn,Mod) do /* Weaker version of above */ \
|
||||
if(!(Fp = fopen(Fn,Mod))) \
|
||||
fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
|
||||
while(0)
|
||||
|
||||
|
||||
struct stack_t {
|
||||
unsigned int pos; /* which function? */
|
||||
unsigned long time; /* Time that this was entered */
|
||||
unsigned long children; /* Time spent in called funcs */
|
||||
};
|
||||
|
||||
static struct stack_t fn_stack[STACKSIZ+1];
|
||||
|
||||
static unsigned int stacktop = 0; /* Lowest stack position is a dummy */
|
||||
|
||||
static unsigned long tot_time = 0;
|
||||
static unsigned long tot_calls = 0;
|
||||
static unsigned long highstack = 0;
|
||||
static unsigned long lowstack = (ulong) ~0;
|
||||
|
||||
/*
|
||||
* top() returns a pointer to the top item on the stack.
|
||||
* (was a function, now a macro)
|
||||
*/
|
||||
|
||||
#define top() &fn_stack[stacktop]
|
||||
|
||||
/*
|
||||
* Push - Push the given record on the stack.
|
||||
*/
|
||||
|
||||
void push (name_pos, time_entered)
|
||||
register unsigned int name_pos;
|
||||
register unsigned long time_entered;
|
||||
{
|
||||
register struct stack_t *t;
|
||||
|
||||
DBUG_ENTER("push");
|
||||
if (++stacktop > STACKSIZ) {
|
||||
fprintf (DBUG_FILE,"%s: stack overflow (%s:%d)\n",
|
||||
my_name, __FILE__, __LINE__);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
DBUG_PRINT ("push", ("%d %ld",name_pos,time_entered));
|
||||
t = &fn_stack[stacktop];
|
||||
t -> pos = name_pos;
|
||||
t -> time = time_entered;
|
||||
t -> children = 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop - pop the top item off the stack, assigning the field values
|
||||
* to the arguments. Returns 0 on stack underflow, or on popping first
|
||||
* item off stack.
|
||||
*/
|
||||
|
||||
unsigned int pop (name_pos, time_entered, child_time)
|
||||
register unsigned int *name_pos;
|
||||
register unsigned long *time_entered;
|
||||
register unsigned long *child_time;
|
||||
{
|
||||
register struct stack_t *temp;
|
||||
register unsigned int rtnval;
|
||||
|
||||
DBUG_ENTER ("pop");
|
||||
|
||||
if (stacktop < 1) {
|
||||
rtnval = 0;
|
||||
} else {
|
||||
temp = &fn_stack[stacktop];
|
||||
*name_pos = temp->pos;
|
||||
*time_entered = temp->time;
|
||||
*child_time = temp->children;
|
||||
DBUG_PRINT ("pop", ("%d %lu %lu",*name_pos,*time_entered,*child_time));
|
||||
rtnval = stacktop--;
|
||||
}
|
||||
DBUG_RETURN (rtnval);
|
||||
}
|
||||
|
||||
/*
|
||||
* We keep the function info in another array (serves as a simple
|
||||
* symbol table)
|
||||
*/
|
||||
|
||||
struct module_t {
|
||||
char *name;
|
||||
unsigned long m_time;
|
||||
unsigned long m_calls;
|
||||
unsigned long m_stkuse;
|
||||
};
|
||||
|
||||
static struct module_t modules[MAXPROCS];
|
||||
|
||||
/*
|
||||
* We keep a binary search tree in order to look up function names
|
||||
* quickly (and sort them at the end.
|
||||
*/
|
||||
|
||||
struct bnode {
|
||||
unsigned int lchild; /* Index of left subtree */
|
||||
unsigned int rchild; /* Index of right subtree */
|
||||
unsigned int pos; /* Index of module_name entry */
|
||||
};
|
||||
|
||||
static struct bnode s_table[MAXPROCS];
|
||||
|
||||
static unsigned int n_items = 0; /* No. of items in the array so far */
|
||||
|
||||
/*
|
||||
* Need a function to allocate space for a string and squirrel it away.
|
||||
*/
|
||||
|
||||
char *strsave (s)
|
||||
char *s;
|
||||
{
|
||||
register char *retval;
|
||||
register unsigned int len;
|
||||
|
||||
DBUG_ENTER ("strsave");
|
||||
DBUG_PRINT ("strsave", ("%s",s));
|
||||
if (!s || (len = strlen (s)) == 0) {
|
||||
DBUG_RETURN (0);
|
||||
}
|
||||
MALLOC (retval, ++len, char);
|
||||
strcpy (retval, s);
|
||||
DBUG_RETURN (retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* add() - adds m_name to the table (if not already there), and returns
|
||||
* the index of its location in the table. Checks s_table (which is a
|
||||
* binary search tree) to see whether or not it should be added.
|
||||
*/
|
||||
|
||||
unsigned int add (m_name)
|
||||
char *m_name;
|
||||
{
|
||||
register unsigned int ind = 0;
|
||||
register int cmp;
|
||||
|
||||
DBUG_ENTER ("add");
|
||||
if (n_items == 0) { /* First item to be added */
|
||||
s_table[0].pos = ind;
|
||||
s_table[0].lchild = s_table[0].rchild = MAXPROCS;
|
||||
addit:
|
||||
modules[n_items].name = strsave (m_name);
|
||||
modules[n_items].m_time = 0;
|
||||
modules[n_items].m_calls = 0;
|
||||
modules[n_items].m_stkuse = 0;
|
||||
DBUG_RETURN (n_items++);
|
||||
}
|
||||
while ((cmp = strcmp (m_name,modules[ind].name))) {
|
||||
if (cmp < 0) { /* In left subtree */
|
||||
if (s_table[ind].lchild == MAXPROCS) {
|
||||
/* Add as left child */
|
||||
if (n_items >= MAXPROCS) {
|
||||
fprintf (DBUG_FILE,
|
||||
"%s: Too many functions being profiled\n",
|
||||
my_name);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
s_table[n_items].pos = s_table[ind].lchild = n_items;
|
||||
s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;
|
||||
#ifdef notdef
|
||||
modules[n_items].name = strsave (m_name);
|
||||
modules[n_items].m_time = modules[n_items].m_calls = 0;
|
||||
DBUG_RETURN (n_items++);
|
||||
#else
|
||||
goto addit;
|
||||
#endif
|
||||
|
||||
}
|
||||
ind = s_table[ind].lchild; /* else traverse l-tree */
|
||||
} else {
|
||||
if (s_table[ind].rchild == MAXPROCS) {
|
||||
/* Add as right child */
|
||||
if (n_items >= MAXPROCS) {
|
||||
fprintf (DBUG_FILE,
|
||||
"%s: Too many functions being profiled\n",
|
||||
my_name);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
s_table[n_items].pos = s_table[ind].rchild = n_items;
|
||||
s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;
|
||||
#ifdef notdef
|
||||
modules[n_items].name = strsave (m_name);
|
||||
modules[n_items].m_time = modules[n_items].m_calls = 0;
|
||||
DBUG_RETURN (n_items++);
|
||||
#else
|
||||
goto addit;
|
||||
#endif
|
||||
|
||||
}
|
||||
ind = s_table[ind].rchild; /* else traverse r-tree */
|
||||
}
|
||||
}
|
||||
DBUG_RETURN (ind);
|
||||
}
|
||||
|
||||
/*
|
||||
* process() - process the input file, filling in the modules table.
|
||||
*/
|
||||
|
||||
void process (inf)
|
||||
FILE *inf;
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char fn_name[64]; /* Max length of fn_name */
|
||||
unsigned long fn_time;
|
||||
unsigned long fn_sbot;
|
||||
unsigned long fn_ssz;
|
||||
unsigned long lastuse;
|
||||
unsigned int pos;
|
||||
unsigned long local_time;
|
||||
unsigned int oldpos;
|
||||
unsigned long oldtime;
|
||||
unsigned long oldchild;
|
||||
struct stack_t *t;
|
||||
|
||||
DBUG_ENTER ("process");
|
||||
while (fgets (buf,BUFSIZ,inf) != NULL) {
|
||||
switch (buf[0]) {
|
||||
case 'E':
|
||||
sscanf (buf+2, "%ld %64s", &fn_time, fn_name);
|
||||
DBUG_PRINT ("erec", ("%ld %s", fn_time, fn_name));
|
||||
pos = add (fn_name);
|
||||
push (pos, fn_time);
|
||||
break;
|
||||
case 'X':
|
||||
sscanf (buf+2, "%ld %64s", &fn_time, fn_name);
|
||||
DBUG_PRINT ("xrec", ("%ld %s", fn_time, fn_name));
|
||||
pos = add (fn_name);
|
||||
/*
|
||||
* An exited function implies that all stacked
|
||||
* functions are also exited, until the matching
|
||||
* function is found on the stack.
|
||||
*/
|
||||
while (pop (&oldpos, &oldtime, &oldchild)) {
|
||||
DBUG_PRINT ("popped", ("%lu %lu", oldtime, oldchild));
|
||||
local_time = fn_time - oldtime;
|
||||
t = top ();
|
||||
t -> children += local_time;
|
||||
DBUG_PRINT ("update", ("%s", modules[t -> pos].name));
|
||||
DBUG_PRINT ("update", ("%lu", t -> children));
|
||||
local_time -= oldchild;
|
||||
modules[oldpos].m_time += local_time;
|
||||
modules[oldpos].m_calls++;
|
||||
tot_time += local_time;
|
||||
tot_calls++;
|
||||
if (pos == oldpos) {
|
||||
goto next_line; /* Should be a break2 */
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Assume that item seen started at time 0.
|
||||
* (True for function main). But initialize
|
||||
* it so that it works the next time too.
|
||||
*/
|
||||
t = top ();
|
||||
local_time = fn_time - t -> time - t -> children;
|
||||
t -> time = fn_time; t -> children = 0;
|
||||
modules[pos].m_time += local_time;
|
||||
modules[pos].m_calls++;
|
||||
tot_time += local_time;
|
||||
tot_calls++;
|
||||
break;
|
||||
case 'S':
|
||||
sscanf (buf+2, "%lx %lx %64s", &fn_sbot, &fn_ssz, fn_name);
|
||||
DBUG_PRINT ("srec", ("%lx %lx %s", fn_sbot, fn_ssz, fn_name));
|
||||
pos = add (fn_name);
|
||||
lastuse = modules[pos].m_stkuse;
|
||||
#if 0
|
||||
/*
|
||||
* Needs further thought. Stack use is determined by
|
||||
* difference in stack between two functions with DBUG_ENTER
|
||||
* macros. If A calls B calls C, where A and C have the
|
||||
* macros, and B doesn't, then B's stack use will be lumped
|
||||
* in with either A's or C's. If somewhere else A calls
|
||||
* C directly, the stack use will seem to change. Just
|
||||
* take the biggest for now...
|
||||
*/
|
||||
if (lastuse > 0 && lastuse != fn_ssz) {
|
||||
fprintf (stderr,
|
||||
"warning - %s stack use changed (%lx to %lx)\n",
|
||||
fn_name, lastuse, fn_ssz);
|
||||
}
|
||||
#endif
|
||||
if (fn_ssz > lastuse) {
|
||||
modules[pos].m_stkuse = fn_ssz;
|
||||
}
|
||||
if (fn_sbot > highstack) {
|
||||
highstack = fn_sbot;
|
||||
} else if (fn_sbot < lowstack) {
|
||||
lowstack = fn_sbot;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "unknown record type '%c'\n", buf[0]);
|
||||
break;
|
||||
}
|
||||
next_line:;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, we've hit eof. If we still have stuff stacked, then we
|
||||
* assume that the user called exit, so give everything the exited
|
||||
* time of fn_time.
|
||||
*/
|
||||
while (pop (&oldpos,&oldtime,&oldchild)) {
|
||||
local_time = fn_time - oldtime;
|
||||
t = top ();
|
||||
t -> children += local_time;
|
||||
local_time -= oldchild;
|
||||
modules[oldpos].m_time += local_time;
|
||||
modules[oldpos].m_calls++;
|
||||
tot_time += local_time;
|
||||
tot_calls++;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
* out_header () -- print out the header of the report.
|
||||
*/
|
||||
|
||||
void out_header (outf)
|
||||
FILE *outf;
|
||||
{
|
||||
DBUG_ENTER ("out_header");
|
||||
if (verbose) {
|
||||
fprintf (outf, "Profile of Execution\n");
|
||||
fprintf (outf, "Execution times are in milliseconds\n\n");
|
||||
fprintf (outf, " Calls\t\t\t Time\n");
|
||||
fprintf (outf, " -----\t\t\t ----\n");
|
||||
fprintf (outf, "Times\tPercentage\tTime Spent\tPercentage\n");
|
||||
fprintf (outf, "Called\tof total\tin Function\tof total Importance\tFunction\n");
|
||||
fprintf (outf, "======\t==========\t===========\t========== ==========\t========\t\n");
|
||||
} else {
|
||||
fprintf (outf, "%ld bytes of stack used, from %lx down to %lx\n\n",
|
||||
highstack - lowstack, highstack, lowstack);
|
||||
fprintf (outf,
|
||||
" %%time sec #call ms/call %%calls weight stack name\n");
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
* out_trailer () - writes out the summary line of the report.
|
||||
*/
|
||||
|
||||
void out_trailer (outf,sum_calls,sum_time)
|
||||
FILE *outf;
|
||||
unsigned long int sum_calls, sum_time;
|
||||
{
|
||||
DBUG_ENTER ("out_trailer");
|
||||
if (verbose)
|
||||
{
|
||||
fprintf(outf, "======\t==========\t===========\t==========\t========\n");
|
||||
fprintf(outf, "%6ld\t%10.2f\t%11ld\t%10.2f\t\t%-15s\n",
|
||||
sum_calls, 100.0, sum_time, 100.0, "Totals");
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
* out_item () - prints out the output line for a single entry,
|
||||
* and sets the calls and time fields appropriately.
|
||||
*/
|
||||
|
||||
void out_item (outf, m,called,timed)
|
||||
FILE *outf;
|
||||
register struct module_t *m;
|
||||
unsigned long int *called, *timed;
|
||||
{
|
||||
char *name = m -> name;
|
||||
register unsigned int calls = m -> m_calls;
|
||||
register unsigned long local_time = m -> m_time;
|
||||
register unsigned long stkuse = m -> m_stkuse;
|
||||
unsigned int import;
|
||||
double per_time = 0.0;
|
||||
double per_calls = 0.0;
|
||||
double ms_per_call, local_ftime;
|
||||
|
||||
DBUG_ENTER ("out_item");
|
||||
|
||||
if (tot_time > 0) {
|
||||
per_time = (double) (local_time * 100) / (double) tot_time;
|
||||
}
|
||||
if (tot_calls > 0) {
|
||||
per_calls = (double) (calls * 100) / (double) tot_calls;
|
||||
}
|
||||
import = (unsigned int) (per_time * per_calls);
|
||||
|
||||
if (verbose) {
|
||||
fprintf (outf, "%6d\t%10.2f\t%11ld\t%10.2f %10d\t%-15s\n",
|
||||
calls, per_calls, local_time, per_time, import, name);
|
||||
} else {
|
||||
ms_per_call = local_time;
|
||||
ms_per_call /= calls;
|
||||
local_ftime = local_time;
|
||||
local_ftime /= 1000;
|
||||
fprintf(outf, "%8.2f%8.3f%8u%8.3f%8.2f%8u%8lu %-s\n",
|
||||
per_time, local_ftime, calls, ms_per_call, per_calls, import,
|
||||
stkuse, name);
|
||||
}
|
||||
*called = calls;
|
||||
*timed = local_time;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
* out_body (outf, root,s_calls,s_time) -- Performs an inorder traversal
|
||||
* on the binary search tree (root). Calls out_item to actually print
|
||||
* the item out.
|
||||
*/
|
||||
|
||||
void out_body (outf, root,s_calls,s_time)
|
||||
FILE *outf;
|
||||
register unsigned int root;
|
||||
register unsigned long int *s_calls, *s_time;
|
||||
{
|
||||
unsigned long int calls, local_time;
|
||||
|
||||
DBUG_ENTER ("out_body");
|
||||
DBUG_PRINT ("out_body", ("%lu,%lu",*s_calls,*s_time));
|
||||
if (root == MAXPROCS) {
|
||||
DBUG_PRINT ("out_body", ("%lu,%lu",*s_calls,*s_time));
|
||||
} else {
|
||||
while (root != MAXPROCS) {
|
||||
out_body (outf, s_table[root].lchild,s_calls,s_time);
|
||||
out_item (outf, &modules[s_table[root].pos],&calls,&local_time);
|
||||
DBUG_PRINT ("out_body", ("-- %lu -- %lu --", calls, local_time));
|
||||
*s_calls += calls;
|
||||
*s_time += local_time;
|
||||
root = s_table[root].rchild;
|
||||
}
|
||||
DBUG_PRINT ("out_body", ("%lu,%lu", *s_calls, *s_time));
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
* output () - print out a nice sorted output report on outf.
|
||||
*/
|
||||
|
||||
void output (outf)
|
||||
FILE *outf;
|
||||
{
|
||||
unsigned long int sum_calls = 0;
|
||||
unsigned long int sum_time = 0;
|
||||
|
||||
DBUG_ENTER ("output");
|
||||
if (n_items == 0) {
|
||||
fprintf (outf, "%s: No functions to trace\n", my_name);
|
||||
exit (EX_DATAERR);
|
||||
}
|
||||
out_header (outf);
|
||||
out_body (outf, 0,&sum_calls,&sum_time);
|
||||
out_trailer (outf, sum_calls,sum_time);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
#define usage() fprintf (DBUG_FILE,"Usage: %s [-v] [prof-file]\n",my_name)
|
||||
|
||||
#ifdef MSDOS
|
||||
extern int getopt(int argc, char **argv, char *opts);
|
||||
#endif
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
register int c;
|
||||
int badflg = 0;
|
||||
FILE *infile;
|
||||
FILE *outfile = {stdout};
|
||||
|
||||
#ifdef THREAD
|
||||
#if defined(HAVE_PTHREAD_INIT)
|
||||
pthread_init(); /* Must be called before DBUG_ENTER */
|
||||
#endif
|
||||
my_thread_global_init();
|
||||
#endif /* THREAD */
|
||||
{
|
||||
DBUG_ENTER ("main");
|
||||
DBUG_PROCESS (argv[0]);
|
||||
my_name = argv[0];
|
||||
while ((c = getopt (argc,argv,"#:v")) != EOF) {
|
||||
switch (c) {
|
||||
case '#': /* Debugging Macro enable */
|
||||
DBUG_PUSH (optarg);
|
||||
break;
|
||||
case 'v': /* Verbose mode */
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
badflg++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (badflg) {
|
||||
usage ();
|
||||
DBUG_RETURN (EX_USAGE);
|
||||
}
|
||||
if (optind < argc) {
|
||||
FILEOPEN (infile, argv[optind], "r");
|
||||
} else {
|
||||
FILEOPEN (infile, PRO_FILE, "r");
|
||||
}
|
||||
process (infile);
|
||||
output (outfile);
|
||||
DBUG_RETURN (EX_OK);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MSDOS
|
||||
|
||||
/*
|
||||
* From [email protected] (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985
|
||||
* Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET
|
||||
* Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP
|
||||
* Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix
|
||||
* From: [email protected] (Moderator, John Quarterman)
|
||||
* Newsgroups: mod.std.unix
|
||||
* Subject: public domain AT&T getopt source
|
||||
* Message-ID: <[email protected]>
|
||||
* Date: 3 Nov 85 19:34:15 GMT
|
||||
* Date-Received: 4 Nov 85 12:25:09 GMT
|
||||
* Organization: IEEE/P1003 Portable Operating System Environment Committee
|
||||
* Lines: 91
|
||||
* Approved: [email protected]
|
||||
*
|
||||
* Here's something you've all been waiting for: the AT&T public domain
|
||||
* source for getopt(3). It is the code which was given out at the 1985
|
||||
* UNIFORUM conference in Dallas. I obtained it by electronic mail
|
||||
* directly from AT&T. The people there assure me that it is indeed
|
||||
* in the public domain.
|
||||
*
|
||||
* There is no manual page. That is because the one they gave out at
|
||||
* UNIFORUM was slightly different from the current System V Release 2
|
||||
* manual page. The difference apparently involved a note about the
|
||||
* famous rules 5 and 6, recommending using white space between an option
|
||||
* and its first argument, and not grouping options that have arguments.
|
||||
* Getopt itself is currently lenient about both of these things White
|
||||
* space is allowed, but not mandatory, and the last option in a group can
|
||||
* have an argument. That particular version of the man page evidently
|
||||
* has no official existence, and my source at AT&T did not send a copy.
|
||||
* The current SVR2 man page reflects the actual behavor of this getopt.
|
||||
* However, I am not about to post a copy of anything licensed by AT&T.
|
||||
*
|
||||
* I will submit this source to Berkeley as a bug fix.
|
||||
*
|
||||
* I, personally, make no claims or guarantees of any kind about the
|
||||
* following source. I did compile it to get some confidence that
|
||||
* it arrived whole, but beyond that you're on your own.
|
||||
*
|
||||
*/
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
int opterr = 1;
|
||||
int optind = 1;
|
||||
int optopt;
|
||||
char *optarg;
|
||||
|
||||
static void _ERR(s,c,argv)
|
||||
char *s;
|
||||
int c;
|
||||
char *argv[];
|
||||
{
|
||||
char errbuf[3];
|
||||
|
||||
if (opterr) {
|
||||
errbuf[0] = c;
|
||||
errbuf[1] = '\n';
|
||||
(void) fprintf(stderr, "%s", argv[0]);
|
||||
(void) fprintf(stderr, "%s", s);
|
||||
(void) fprintf(stderr, "%s", errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
int getopt(argc, argv, opts)
|
||||
int argc;
|
||||
char **argv, *opts;
|
||||
{
|
||||
static int sp = 1;
|
||||
register int c;
|
||||
register char *cp;
|
||||
|
||||
if(sp == 1)
|
||||
if(optind >= argc ||
|
||||
argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
return(EOF);
|
||||
else if(strcmp(argv[optind], "--") == 0) {
|
||||
optind++;
|
||||
return(EOF);
|
||||
}
|
||||
optopt = c = argv[optind][sp];
|
||||
if(c == ':' || (cp=strchr(opts, c)) == NULL) {
|
||||
_ERR(": illegal option -- ", c, argv);
|
||||
if(argv[optind][++sp] == '\0') {
|
||||
optind++;
|
||||
sp = 1;
|
||||
}
|
||||
return('?');
|
||||
}
|
||||
if(*++cp == ':') {
|
||||
if(argv[optind][sp+1] != '\0')
|
||||
optarg = &argv[optind++][sp+1];
|
||||
else if(++optind >= argc) {
|
||||
_ERR(": option requires an argument -- ", c, argv);
|
||||
sp = 1;
|
||||
return('?');
|
||||
} else
|
||||
optarg = argv[optind++];
|
||||
sp = 1;
|
||||
} else {
|
||||
if(argv[optind][++sp] == '\0') {
|
||||
sp = 1;
|
||||
optind++;
|
||||
}
|
||||
optarg = NULL;
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
#endif /* !unix && !xenix */
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
#error This file is not used in MySQL - see ../include/my_dbug.h instead
|
||||
/******************************************************************************
|
||||
* *
|
||||
* N O T I C E *
|
||||
* *
|
||||
* Copyright Abandoned, 1987, Fred Fish *
|
||||
* *
|
||||
* *
|
||||
* This previously copyrighted work has been placed into the public *
|
||||
* domain by the author and may be freely used for any purpose, *
|
||||
* private or commercial. *
|
||||
* *
|
||||
* Because of the number of inquiries I was receiving about the use *
|
||||
* of this product in commercially developed works I have decided to *
|
||||
* simply make it public domain to further its unrestricted use. I *
|
||||
* specifically would be most happy to see this material become a *
|
||||
* part of the standard Unix distributions by AT&T and the Berkeley *
|
||||
* Computer Science Research Group, and a standard part of the GNU *
|
||||
* system from the Free Software Foundation. *
|
||||
* *
|
||||
* I would appreciate it, as a courtesy, if this notice is left in *
|
||||
* all copies and derivative works. Thank you. *
|
||||
* *
|
||||
* The author makes no warranty of any kind with respect to this *
|
||||
* product and explicitly disclaims any implied warranties of mer- *
|
||||
* chantability or fitness for any particular purpose. *
|
||||
* *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* FILE
|
||||
*
|
||||
* dbug.h user include file for programs using the dbug package
|
||||
*
|
||||
* SYNOPSIS
|
||||
*
|
||||
* #include <local/dbug.h>
|
||||
*
|
||||
* SCCS ID
|
||||
*
|
||||
* @(#)dbug.h 1.13 7/17/89
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Programs which use the dbug package must include this file.
|
||||
* It contains the appropriate macros to call support routines
|
||||
* in the dbug runtime library.
|
||||
*
|
||||
* To disable compilation of the macro expansions define the
|
||||
* preprocessor symbol "DBUG_OFF". This will result in null
|
||||
* macros expansions so that the resulting code will be smaller
|
||||
* and faster. (The difference may be smaller than you think
|
||||
* so this step is recommended only when absolutely necessary).
|
||||
* In general, tradeoffs between space and efficiency are
|
||||
* decided in favor of efficiency since space is seldom a
|
||||
* problem on the new machines).
|
||||
*
|
||||
* All externally visible symbol names follow the pattern
|
||||
* "_db_xxx..xx_" to minimize the possibility of a dbug package
|
||||
* symbol colliding with a user defined symbol.
|
||||
*
|
||||
* The DBUG_<N> style macros are obsolete and should not be used
|
||||
* in new code. Macros to map them to instances of DBUG_PRINT
|
||||
* are provided for compatibility with older code. They may go
|
||||
* away completely in subsequent releases.
|
||||
*
|
||||
* AUTHOR
|
||||
*
|
||||
* Fred Fish
|
||||
* (Currently employed by Motorola Computer Division, Tempe, Az.)
|
||||
* hao!noao!mcdsun!fnf
|
||||
* (602) 438-3614
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internally used dbug variables which must be global.
|
||||
*/
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
extern int _db_on_; /* TRUE if debug currently enabled */
|
||||
extern FILE *_db_fp_; /* Current debug output stream */
|
||||
extern char *_db_process_; /* Name of current process */
|
||||
extern int _db_keyword_ (); /* Accept/reject keyword */
|
||||
extern void _db_push_ (); /* Push state, set up new state */
|
||||
extern void _db_pop_ (); /* Pop previous debug state */
|
||||
extern void _db_enter_ (); /* New user function entered */
|
||||
extern void _db_return_ (); /* User function return */
|
||||
extern void _db_pargs_ (); /* Remember args for line */
|
||||
extern void _db_doprnt_ (); /* Print debug output */
|
||||
extern void _db_setjmp_ (); /* Save debugger environment */
|
||||
extern void _db_longjmp_ (); /* Restore debugger environment */
|
||||
extern void _db_dump_(); /* Dump memory */
|
||||
# endif
|
||||
|
||||
|
||||
/*
|
||||
* These macros provide a user interface into functions in the
|
||||
* dbug runtime support library. They isolate users from changes
|
||||
* in the MACROS and/or runtime support.
|
||||
*
|
||||
* The symbols "__LINE__" and "__FILE__" are expanded by the
|
||||
* preprocessor to the current source file line number and file
|
||||
* name respectively.
|
||||
*
|
||||
* WARNING --- Because the DBUG_ENTER macro allocates space on
|
||||
* the user function's stack, it must precede any executable
|
||||
* statements in the user function.
|
||||
*
|
||||
*/
|
||||
|
||||
# ifdef DBUG_OFF
|
||||
# define DBUG_ENTER(a1)
|
||||
# define DBUG_RETURN(a1) return(a1)
|
||||
# define DBUG_VOID_RETURN return
|
||||
# define DBUG_EXECUTE(keyword,a1)
|
||||
# define DBUG_PRINT(keyword,arglist)
|
||||
# define DBUG_2(keyword,format) /* Obsolete */
|
||||
# define DBUG_3(keyword,format,a1) /* Obsolete */
|
||||
# define DBUG_4(keyword,format,a1,a2) /* Obsolete */
|
||||
# define DBUG_5(keyword,format,a1,a2,a3) /* Obsolete */
|
||||
# define DBUG_PUSH(a1)
|
||||
# define DBUG_POP()
|
||||
# define DBUG_PROCESS(a1)
|
||||
# define DBUG_FILE (stderr)
|
||||
# define DBUG_SETJMP setjmp
|
||||
# define DBUG_LONGJMP longjmp
|
||||
# define DBUG_DUMP(keyword,a1)
|
||||
# else
|
||||
# define DBUG_ENTER(a) \
|
||||
auto char *_db_func_; auto char *_db_file_; auto int _db_level_; \
|
||||
auto char **_db_framep_; \
|
||||
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
|
||||
&_db_framep_)
|
||||
# define DBUG_LEAVE \
|
||||
(_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
|
||||
# define DBUG_RETURN(a1) return (DBUG_LEAVE, (a1))
|
||||
/* define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} Alternate form */
|
||||
# define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
|
||||
# define DBUG_EXECUTE(keyword,a1) \
|
||||
{if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
|
||||
# define DBUG_PRINT(keyword,arglist) \
|
||||
{if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
|
||||
# define DBUG_2(keyword,format) \
|
||||
DBUG_PRINT(keyword,(format)) /* Obsolete */
|
||||
# define DBUG_3(keyword,format,a1) \
|
||||
DBUG_PRINT(keyword,(format,a1)) /* Obsolete */
|
||||
# define DBUG_4(keyword,format,a1,a2) \
|
||||
DBUG_PRINT(keyword,(format,a1,a2)) /* Obsolete */
|
||||
# define DBUG_5(keyword,format,a1,a2,a3) \
|
||||
DBUG_PRINT(keyword,(format,a1,a2,a3)) /* Obsolete */
|
||||
# define DBUG_PUSH(a1) _db_push_ (a1)
|
||||
# define DBUG_POP() _db_pop_ ()
|
||||
# define DBUG_PROCESS(a1) (_db_process_ = a1)
|
||||
# define DBUG_FILE (_db_fp_)
|
||||
# define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
|
||||
# define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
|
||||
# define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2)
|
||||
# endif
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
printf ("argv[0] = %d\n", argv[0]);
|
||||
/*
|
||||
* Rest of program
|
||||
*/
|
||||
printf ("== done ==\n");
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
int debug = 0;
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
/* printf ("argv = %x\n", argv) */
|
||||
if (debug) printf ("argv[0] = %d\n", argv[0]);
|
||||
/*
|
||||
* Rest of program
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printf ("== done ==\n");
|
||||
#endif
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
# ifdef DEBUG
|
||||
printf ("argv[0] = %d\n", argv[0]);
|
||||
# endif
|
||||
/*
|
||||
* Rest of program
|
||||
*/
|
||||
# ifdef DEBUG
|
||||
printf ("== done ==\n");
|
||||
# endif
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#ifdef DBUG_OFF /* We are testing dbug */
|
||||
|
||||
int factorial(register int value) {
|
||||
if(value > 1) {
|
||||
value *= factorial(value-1);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <my_global.h>
|
||||
|
||||
int factorial (
|
||||
register int value)
|
||||
{
|
||||
DBUG_ENTER ("factorial");
|
||||
DBUG_PRINT ("find", ("find %d factorial", value));
|
||||
if (value > 1) {
|
||||
value *= factorial (value - 1);
|
||||
}
|
||||
DBUG_PRINT ("result", ("result is %d", value));
|
||||
DBUG_RETURN (value);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
#include <dbug.h>
|
||||
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int result, ix;
|
||||
extern int factorial(int);
|
||||
DBUG_ENTER ("main");
|
||||
DBUG_PROCESS (argv[0]);
|
||||
for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
|
||||
switch (argv[ix][1]) {
|
||||
case '#':
|
||||
DBUG_PUSH (&(argv[ix][2]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; ix < argc; ix++) {
|
||||
DBUG_PRINT ("args", ("argv[%d] = %s", ix, argv[ix]));
|
||||
result = factorial (atoi(argv[ix]));
|
||||
printf ("%d\n", result);
|
||||
}
|
||||
DBUG_RETURN (0);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
this is modified version of the original example main.c
|
||||
fixed so that it could compile and run in MySQL source tree
|
||||
*/
|
||||
|
||||
#ifdef DBUG_OFF /* We are testing dbug */
|
||||
#undef DBUG_OFF
|
||||
#endif
|
||||
|
||||
#include <my_global.h> /* This includes dbug.h */
|
||||
#include <my_pthread.h>
|
||||
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register int result, ix;
|
||||
extern int factorial(int);
|
||||
#if defined(HAVE_PTHREAD_INIT) && defined(THREAD)
|
||||
pthread_init(); /* Must be called before DBUG_ENTER */
|
||||
#endif
|
||||
#ifdef THREAD
|
||||
my_thread_global_init();
|
||||
#endif
|
||||
{
|
||||
DBUG_ENTER ("main");
|
||||
DBUG_PROCESS (argv[0]);
|
||||
for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
|
||||
switch (argv[ix][1]) {
|
||||
case '#':
|
||||
DBUG_PUSH (&(argv[ix][2]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; ix < argc; ix++) {
|
||||
DBUG_PRINT ("args", ("argv[%d] = %s", ix, argv[ix]));
|
||||
result = factorial (atoi(argv[ix]));
|
||||
printf ("%d\n", result);
|
||||
}
|
||||
DBUG_RETURN (0);
|
||||
}
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
/* Declarate _sanity() if not declared in main program */
|
||||
|
||||
#include <my_global.h>
|
||||
|
||||
extern int _sanity(const char *file,uint line);
|
||||
|
||||
#if defined(SAFEMALLOC) && !defined(MASTER) /* Avoid errors in MySQL */
|
||||
int _sanity(const char * file __attribute__((unused)),
|
||||
uint line __attribute__((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Vendored
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
A program to test DBUG features. Used by tests-t.pl
|
||||
*/
|
||||
|
||||
char *push1=0;
|
||||
|
||||
#include <my_global.h> /* This includes dbug.h */
|
||||
#include <my_pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
const char *func3()
|
||||
{
|
||||
DBUG_ENTER("func3");
|
||||
DBUG_RETURN(DBUG_EVALUATE("ret3", "ok", "ko"));
|
||||
}
|
||||
|
||||
void func2()
|
||||
{
|
||||
const char *s;
|
||||
DBUG_ENTER("func2");
|
||||
s=func3();
|
||||
DBUG_PRINT("info", ("s=%s", s));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
int func1()
|
||||
{
|
||||
DBUG_ENTER("func1");
|
||||
func2();
|
||||
if (push1)
|
||||
{
|
||||
DBUG_PUSH(push1);
|
||||
fprintf(DBUG_FILE, "=> push1\n");
|
||||
}
|
||||
DBUG_RETURN(10);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
#ifdef DBUG_OFF
|
||||
return 1;
|
||||
#endif
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
#if defined(HAVE_PTHREAD_INIT) && defined(THREAD)
|
||||
pthread_init(); /* Must be called before DBUG_ENTER */
|
||||
#endif
|
||||
#ifdef THREAD
|
||||
my_thread_global_init();
|
||||
#endif
|
||||
dup2(1, 2);
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (strncmp(argv[i], "--push1=", 8) == 0)
|
||||
push1=argv[i]+8;
|
||||
else
|
||||
DBUG_PUSH (argv[i]);
|
||||
}
|
||||
{
|
||||
DBUG_ENTER ("main");
|
||||
DBUG_PROCESS ("dbug-tests");
|
||||
func1();
|
||||
DBUG_EXECUTE_IF("dump",
|
||||
{
|
||||
char s[1000];
|
||||
DBUG_EXPLAIN(s, sizeof(s)-1);
|
||||
DBUG_DUMP("dump", (uchar*)s, strlen(s));
|
||||
});
|
||||
DBUG_EXECUTE_IF("push", DBUG_PUSH("+t"); );
|
||||
DBUG_EXECUTE("execute", fprintf(DBUG_FILE, "=> execute\n"); );
|
||||
DBUG_EXECUTE_IF("set", DBUG_SET("+F"); );
|
||||
fprintf(DBUG_FILE, "=> evaluate: %s\n",
|
||||
DBUG_EVALUATE("evaluate", "ON", "OFF"));
|
||||
fprintf(DBUG_FILE, "=> evaluate_if: %s\n",
|
||||
DBUG_EVALUATE_IF("evaluate_if", "ON", "OFF"));
|
||||
DBUG_EXECUTE_IF("pop", DBUG_POP(); );
|
||||
{
|
||||
char s[1000] __attribute__((unused));
|
||||
DBUG_EXPLAIN(s, sizeof(s)-1);
|
||||
DBUG_PRINT("explain", ("dbug explained: %s", s));
|
||||
}
|
||||
func2();
|
||||
DBUG_RETURN (0);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/* character-class table */
|
||||
|
||||
#define CCLASS_ALNUM 0
|
||||
#define CCLASS_ALPHA 1
|
||||
#define CCLASS_BLANK 2
|
||||
#define CCLASS_CNTRL 3
|
||||
#define CCLASS_DIGIT 4
|
||||
#define CCLASS_GRAPH 5
|
||||
#define CCLASS_LOWER 6
|
||||
#define CCLASS_PRINT 7
|
||||
#define CCLASS_PUNCT 8
|
||||
#define CCLASS_SPACE 9
|
||||
#define CCLASS_UPPER 10
|
||||
#define CCLASS_XDIGIT 11
|
||||
#define CCLASS_LAST 12
|
||||
|
||||
extern struct cclass {
|
||||
const char *name;
|
||||
const char *chars;
|
||||
const char *multis;
|
||||
uint mask;
|
||||
} cclasses[];
|
||||
Vendored
+104
@@ -0,0 +1,104 @@
|
||||
/* character-name table */
|
||||
static struct cname {
|
||||
const char *name;
|
||||
const char code;
|
||||
} cnames[] = {
|
||||
{"NUL", '\0'},
|
||||
{"SOH", '\001'},
|
||||
{"STX", '\002'},
|
||||
{"ETX", '\003'},
|
||||
{"EOT", '\004'},
|
||||
{"ENQ", '\005'},
|
||||
{"ACK", '\006'},
|
||||
{"BEL", '\007'},
|
||||
{"alert", '\007'},
|
||||
{"BS", '\010'},
|
||||
{"backspace", '\b'},
|
||||
{"HT", '\011'},
|
||||
{"tab", '\t'},
|
||||
{"LF", '\012'},
|
||||
{"newline", '\n'},
|
||||
{"VT", '\013'},
|
||||
{"vertical-tab",'\v'},
|
||||
{"FF", '\014'},
|
||||
{"form-feed", '\f'},
|
||||
{"CR", '\015'},
|
||||
{"carriage-return", '\r'},
|
||||
{"SO", '\016'},
|
||||
{"SI", '\017'},
|
||||
{"DLE", '\020'},
|
||||
{"DC1", '\021'},
|
||||
{"DC2", '\022'},
|
||||
{"DC3", '\023'},
|
||||
{"DC4", '\024'},
|
||||
{"NAK", '\025'},
|
||||
{"SYN", '\026'},
|
||||
{"ETB", '\027'},
|
||||
{"CAN", '\030'},
|
||||
{"EM", '\031'},
|
||||
{"SUB", '\032'},
|
||||
{"ESC", '\033'},
|
||||
{"IS4", '\034'},
|
||||
{"FS", '\034'},
|
||||
{"IS3", '\035'},
|
||||
{"GS", '\035'},
|
||||
{"IS2", '\036'},
|
||||
{"RS", '\036'},
|
||||
{"IS1", '\037'},
|
||||
{"US", '\037'},
|
||||
{"space", ' '},
|
||||
{"exclamation-mark", '!'},
|
||||
{"quotation-mark", '"'},
|
||||
{"number-sign", '#'},
|
||||
{"dollar-sign", '$'},
|
||||
{"percent-sign", '%'},
|
||||
{"ampersand", '&'},
|
||||
{"apostrophe", '\''},
|
||||
{"left-parenthesis", '('},
|
||||
{"right-parenthesis", ')'},
|
||||
{"asterisk", '*'},
|
||||
{"plus-sign", '+'},
|
||||
{"comma", ','},
|
||||
{"hyphen", '-'},
|
||||
{"hyphen-minus", '-'},
|
||||
{"period", '.'},
|
||||
{"full-stop", '.'},
|
||||
{"slash", '/'},
|
||||
{"solidus", '/'},
|
||||
{"zero", '0'},
|
||||
{"one", '1'},
|
||||
{"two", '2'},
|
||||
{"three", '3'},
|
||||
{"four", '4'},
|
||||
{"five", '5'},
|
||||
{"six", '6'},
|
||||
{"seven", '7'},
|
||||
{"eight", '8'},
|
||||
{"nine", '9'},
|
||||
{"colon", ':'},
|
||||
{"semicolon", ';'},
|
||||
{"less-than-sign", '<'},
|
||||
{"equals-sign", '='},
|
||||
{"greater-than-sign", '>'},
|
||||
{"question-mark", '?'},
|
||||
{"commercial-at", '@'},
|
||||
{"left-square-bracket", '['},
|
||||
{"backslash", '\\'},
|
||||
{"reverse-solidus", '\\'},
|
||||
{"right-square-bracket",']'},
|
||||
{"circumflex", '^'},
|
||||
{"circumflex-accent", '^'},
|
||||
{"underscore", '_'},
|
||||
{"low-line", '_'},
|
||||
{"grave-accent", '`'},
|
||||
{"left-brace", '{'},
|
||||
{"left-curly-bracket", '{'},
|
||||
{"vertical-line", '|'},
|
||||
{"right-brace", '}'},
|
||||
{"right-curly-bracket", '}'},
|
||||
{"tilde", '~'},
|
||||
{"DEL", '\177'},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
|
||||
Vendored
+246
@@ -0,0 +1,246 @@
|
||||
#include <my_global.h>
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "my_regex.h"
|
||||
#include "utils.h"
|
||||
#include "regex2.h"
|
||||
#include "debug.ih"
|
||||
|
||||
/* Added extra paramter to regchar to remove static buffer ; Monty 96.11.27 */
|
||||
|
||||
/*
|
||||
- regprint - print a regexp for debugging
|
||||
== void regprint(regex_t *r, FILE *d);
|
||||
*/
|
||||
void
|
||||
regprint(r, d)
|
||||
my_regex_t *r;
|
||||
FILE *d;
|
||||
{
|
||||
register struct re_guts *g = r->re_g;
|
||||
register int i;
|
||||
register int c;
|
||||
register int last;
|
||||
int nincat[NC];
|
||||
char buf[10];
|
||||
|
||||
fprintf(d, "%ld states, %d categories", (long)g->nstates,
|
||||
g->ncategories);
|
||||
fprintf(d, ", first %ld last %ld", (long)g->firststate,
|
||||
(long)g->laststate);
|
||||
if (g->iflags&USEBOL)
|
||||
fprintf(d, ", USEBOL");
|
||||
if (g->iflags&USEEOL)
|
||||
fprintf(d, ", USEEOL");
|
||||
if (g->iflags&BAD)
|
||||
fprintf(d, ", BAD");
|
||||
if (g->nsub > 0)
|
||||
fprintf(d, ", nsub=%ld", (long)g->nsub);
|
||||
if (g->must != NULL)
|
||||
fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
|
||||
g->must);
|
||||
if (g->backrefs)
|
||||
fprintf(d, ", backrefs");
|
||||
if (g->nplus > 0)
|
||||
fprintf(d, ", nplus %ld", (long)g->nplus);
|
||||
fprintf(d, "\n");
|
||||
s_print(r->charset, g, d);
|
||||
for (i = 0; i < g->ncategories; i++) {
|
||||
nincat[i] = 0;
|
||||
for (c = CHAR_MIN; c <= CHAR_MAX; c++)
|
||||
if (g->categories[c] == i)
|
||||
nincat[i]++;
|
||||
}
|
||||
fprintf(d, "cc0#%d", nincat[0]);
|
||||
for (i = 1; i < g->ncategories; i++)
|
||||
if (nincat[i] == 1) {
|
||||
for (c = CHAR_MIN; c <= CHAR_MAX; c++)
|
||||
if (g->categories[c] == i)
|
||||
break;
|
||||
fprintf(d, ", %d=%s", i, regchar(r->charset,c,buf));
|
||||
}
|
||||
fprintf(d, "\n");
|
||||
for (i = 1; i < g->ncategories; i++)
|
||||
if (nincat[i] != 1) {
|
||||
fprintf(d, "cc%d\t", i);
|
||||
last = -1;
|
||||
for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */
|
||||
if (c <= CHAR_MAX && g->categories[c] == i) {
|
||||
if (last < 0) {
|
||||
fprintf(d, "%s", regchar(r->charset,c,buf));
|
||||
last = c;
|
||||
}
|
||||
} else {
|
||||
if (last >= 0) {
|
||||
if (last != c-1)
|
||||
fprintf(d, "-%s",
|
||||
regchar(r->charset,c-1,buf));
|
||||
last = -1;
|
||||
}
|
||||
}
|
||||
fprintf(d, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- s_print - print the strip for debugging
|
||||
== static void s_print(register struct re_guts *g, FILE *d);
|
||||
*/
|
||||
static void
|
||||
s_print(charset, g, d)
|
||||
CHARSET_INFO *charset;
|
||||
register struct re_guts *g;
|
||||
FILE *d;
|
||||
{
|
||||
register sop *s;
|
||||
register cset *cs;
|
||||
register int i;
|
||||
register int done = 0;
|
||||
register sop opnd;
|
||||
register int col = 0;
|
||||
register int last;
|
||||
register sopno offset = 2;
|
||||
char buf[10];
|
||||
# define GAP() { if (offset % 5 == 0) { \
|
||||
if (col > 40) { \
|
||||
fprintf(d, "\n\t"); \
|
||||
col = 0; \
|
||||
} else { \
|
||||
fprintf(d, " "); \
|
||||
col++; \
|
||||
} \
|
||||
} else \
|
||||
col++; \
|
||||
offset++; \
|
||||
}
|
||||
|
||||
if (OP(g->strip[0]) != OEND)
|
||||
fprintf(d, "missing initial OEND!\n");
|
||||
for (s = &g->strip[1]; !done; s++) {
|
||||
opnd = OPND(*s);
|
||||
switch (OP(*s)) {
|
||||
case OEND:
|
||||
fprintf(d, "\n");
|
||||
done = 1;
|
||||
break;
|
||||
case OCHAR:
|
||||
if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
|
||||
fprintf(d, "\\%c", (char)opnd);
|
||||
else
|
||||
fprintf(d, "%s", regchar(charset,(char)opnd,buf));
|
||||
break;
|
||||
case OBOL:
|
||||
fprintf(d, "^");
|
||||
break;
|
||||
case OEOL:
|
||||
fprintf(d, "$");
|
||||
break;
|
||||
case OBOW:
|
||||
fprintf(d, "\\{");
|
||||
break;
|
||||
case OEOW:
|
||||
fprintf(d, "\\}");
|
||||
break;
|
||||
case OANY:
|
||||
fprintf(d, ".");
|
||||
break;
|
||||
case OANYOF:
|
||||
fprintf(d, "[(%ld)", (long)opnd);
|
||||
cs = &g->sets[opnd];
|
||||
last = -1;
|
||||
for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */
|
||||
if (CHIN(cs, i) && i < g->csetsize) {
|
||||
if (last < 0) {
|
||||
fprintf(d, "%s", regchar(charset,i,buf));
|
||||
last = i;
|
||||
}
|
||||
} else {
|
||||
if (last >= 0) {
|
||||
if (last != i-1)
|
||||
fprintf(d, "-%s",
|
||||
regchar(charset,i-1,buf));
|
||||
last = -1;
|
||||
}
|
||||
}
|
||||
fprintf(d, "]");
|
||||
break;
|
||||
case OBACK_:
|
||||
fprintf(d, "(\\<%ld>", (long)opnd);
|
||||
break;
|
||||
case O_BACK:
|
||||
fprintf(d, "<%ld>\\)", (long)opnd);
|
||||
break;
|
||||
case OPLUS_:
|
||||
fprintf(d, "(+");
|
||||
if (OP(*(s+opnd)) != O_PLUS)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
break;
|
||||
case O_PLUS:
|
||||
if (OP(*(s-opnd)) != OPLUS_)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
fprintf(d, "+)");
|
||||
break;
|
||||
case OQUEST_:
|
||||
fprintf(d, "(?");
|
||||
if (OP(*(s+opnd)) != O_QUEST)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
break;
|
||||
case O_QUEST:
|
||||
if (OP(*(s-opnd)) != OQUEST_)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
fprintf(d, "?)");
|
||||
break;
|
||||
case OLPAREN:
|
||||
fprintf(d, "((<%ld>", (long)opnd);
|
||||
break;
|
||||
case ORPAREN:
|
||||
fprintf(d, "<%ld>))", (long)opnd);
|
||||
break;
|
||||
case OCH_:
|
||||
fprintf(d, "<");
|
||||
if (OP(*(s+opnd)) != OOR2)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
break;
|
||||
case OOR1:
|
||||
if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
fprintf(d, "|");
|
||||
break;
|
||||
case OOR2:
|
||||
fprintf(d, "|");
|
||||
if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
break;
|
||||
case O_CH:
|
||||
if (OP(*(s-opnd)) != OOR1)
|
||||
fprintf(d, "<%ld>", (long)opnd);
|
||||
fprintf(d, ">");
|
||||
break;
|
||||
default:
|
||||
fprintf(d, "!%ld(%ld)!", OP(*s), opnd);
|
||||
break;
|
||||
}
|
||||
if (!done)
|
||||
GAP();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- regchar - make a character printable
|
||||
== static char *regchar(int ch);
|
||||
*/
|
||||
static char * /* -> representation */
|
||||
regchar(charset,ch,buf)
|
||||
CHARSET_INFO *charset;
|
||||
int ch;
|
||||
char *buf;
|
||||
{
|
||||
|
||||
if (my_isprint(charset,ch) || ch == ' ')
|
||||
sprintf(buf, "%c", ch);
|
||||
else
|
||||
sprintf(buf, "\\%o", ch);
|
||||
return(buf);
|
||||
}
|
||||
+1031
File diff suppressed because it is too large
Load Diff
Vendored
+509
@@ -0,0 +1,509 @@
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "my_regex.h"
|
||||
#include "main.ih"
|
||||
|
||||
char *progname;
|
||||
int debug = 0;
|
||||
int line = 0;
|
||||
int status = 0;
|
||||
|
||||
int copts = REG_EXTENDED;
|
||||
int eopts = 0;
|
||||
regoff_t startoff = 0;
|
||||
regoff_t endoff = 0;
|
||||
|
||||
|
||||
extern int split();
|
||||
extern void regprint();
|
||||
|
||||
/*
|
||||
- main - do the simple case, hand off to regress() for regression
|
||||
*/
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
my_regex_t re;
|
||||
# define NS 10
|
||||
my_regmatch_t subs[NS];
|
||||
char erbuf[100];
|
||||
int err;
|
||||
size_t len;
|
||||
int c;
|
||||
int errflg = 0;
|
||||
register int i;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
while ((c = getopt(argc, argv, "c:e:S:E:x")) != EOF)
|
||||
switch (c) {
|
||||
case 'c': /* compile options */
|
||||
copts = options('c', optarg);
|
||||
break;
|
||||
case 'e': /* execute options */
|
||||
eopts = options('e', optarg);
|
||||
break;
|
||||
case 'S': /* start offset */
|
||||
startoff = (regoff_t)atoi(optarg);
|
||||
break;
|
||||
case 'E': /* end offset */
|
||||
endoff = (regoff_t)atoi(optarg);
|
||||
break;
|
||||
case 'x': /* Debugging. */
|
||||
debug++;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
errflg++;
|
||||
break;
|
||||
}
|
||||
if (errflg) {
|
||||
fprintf(stderr, "usage: %s ", progname);
|
||||
fprintf(stderr, "[-c copt][-C][-d] [re]\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
regress(stdin);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
err = my_regcomp(&re, argv[optind++], copts, &my_charset_latin1);
|
||||
if (err) {
|
||||
len = my_regerror(err, &re, erbuf, sizeof(erbuf));
|
||||
fprintf(stderr, "error %s, %d/%d `%s'\n",
|
||||
eprint(err), (int) len, (int) sizeof(erbuf), erbuf);
|
||||
exit(status);
|
||||
}
|
||||
regprint(&re, stdout);
|
||||
|
||||
if (optind >= argc) {
|
||||
my_regfree(&re);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
if (eopts®_STARTEND) {
|
||||
subs[0].rm_so = startoff;
|
||||
subs[0].rm_eo = strlen(argv[optind]) - endoff;
|
||||
}
|
||||
err = my_regexec(&re, argv[optind], (size_t)NS, subs, eopts);
|
||||
if (err) {
|
||||
len = my_regerror(err, &re, erbuf, sizeof(erbuf));
|
||||
fprintf(stderr, "error %s, %d/%d `%s'\n",
|
||||
eprint(err), (int) len, (int) sizeof(erbuf), erbuf);
|
||||
exit(status);
|
||||
}
|
||||
if (!(copts®_NOSUB)) {
|
||||
len = (int)(subs[0].rm_eo - subs[0].rm_so);
|
||||
if (subs[0].rm_so != -1) {
|
||||
if (len != 0)
|
||||
printf("match `%.*s'\n", (int)len,
|
||||
argv[optind] + subs[0].rm_so);
|
||||
else
|
||||
printf("match `'@%.1s\n",
|
||||
argv[optind] + subs[0].rm_so);
|
||||
}
|
||||
for (i = 1; i < NS; i++)
|
||||
if (subs[i].rm_so != -1)
|
||||
printf("(%d) `%.*s'\n", i,
|
||||
(int)(subs[i].rm_eo - subs[i].rm_so),
|
||||
argv[optind] + subs[i].rm_so);
|
||||
}
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/*
|
||||
- regress - main loop of regression test
|
||||
== void regress(FILE *in);
|
||||
*/
|
||||
void
|
||||
regress(in)
|
||||
FILE *in;
|
||||
{
|
||||
char inbuf[1000];
|
||||
# define MAXF 10
|
||||
char *f[MAXF];
|
||||
int nf;
|
||||
int i;
|
||||
char erbuf[100];
|
||||
size_t ne;
|
||||
const char *badpat = "invalid regular expression";
|
||||
# define SHORT 10
|
||||
const char *bpname = "REG_BADPAT";
|
||||
my_regex_t re;
|
||||
|
||||
while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
|
||||
line++;
|
||||
if (inbuf[0] == '#' || inbuf[0] == '\n')
|
||||
continue; /* NOTE CONTINUE */
|
||||
inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */
|
||||
if (debug)
|
||||
fprintf(stdout, "%d:\n", line);
|
||||
nf = split(inbuf, f, MAXF, "\t\t");
|
||||
if (nf < 3) {
|
||||
fprintf(stderr, "bad input, line %d\n", line);
|
||||
exit(1);
|
||||
}
|
||||
for (i = 0; i < nf; i++)
|
||||
if (strcmp(f[i], "\"\"") == 0)
|
||||
f[i] = (char*) "";
|
||||
if (nf <= 3)
|
||||
f[3] = NULL;
|
||||
if (nf <= 4)
|
||||
f[4] = NULL;
|
||||
rx_try(f[0], f[1], f[2], f[3], f[4], options('c', f[1]));
|
||||
if (opt('&', f[1])) /* try with either type of RE */
|
||||
rx_try(f[0], f[1], f[2], f[3], f[4],
|
||||
options('c', f[1]) &~ REG_EXTENDED);
|
||||
}
|
||||
|
||||
ne = my_regerror(REG_BADPAT, (my_regex_t *)NULL, erbuf, sizeof(erbuf));
|
||||
if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
|
||||
fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
|
||||
erbuf, badpat);
|
||||
status = 1;
|
||||
}
|
||||
ne = my_regerror(REG_BADPAT, (my_regex_t *)NULL, erbuf, (size_t)SHORT);
|
||||
if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
|
||||
ne != strlen(badpat)+1) {
|
||||
fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
|
||||
erbuf, SHORT-1, badpat);
|
||||
status = 1;
|
||||
}
|
||||
ne = my_regerror(REG_ITOA|REG_BADPAT, (my_regex_t *)NULL, erbuf, sizeof(erbuf));
|
||||
if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
|
||||
fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
|
||||
erbuf, bpname);
|
||||
status = 1;
|
||||
}
|
||||
re.re_endp = bpname;
|
||||
ne = my_regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
|
||||
if (atoi(erbuf) != (int)REG_BADPAT) {
|
||||
fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
|
||||
erbuf, (long)REG_BADPAT);
|
||||
status = 1;
|
||||
} else if (ne != strlen(erbuf)+1) {
|
||||
fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
|
||||
erbuf, (long)REG_BADPAT);
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- rx_try - try it, and report on problems
|
||||
== void rx_try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts);
|
||||
*/
|
||||
void
|
||||
rx_try(f0, f1, f2, f3, f4, opts)
|
||||
char *f0;
|
||||
char *f1;
|
||||
char *f2;
|
||||
char *f3;
|
||||
char *f4;
|
||||
int opts; /* may not match f1 */
|
||||
{
|
||||
my_regex_t re;
|
||||
# define NSUBS 10
|
||||
my_regmatch_t subs[NSUBS];
|
||||
# define NSHOULD 15
|
||||
char *should[NSHOULD];
|
||||
int nshould;
|
||||
char erbuf[100];
|
||||
int err;
|
||||
int len;
|
||||
const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
|
||||
register int i;
|
||||
char *grump;
|
||||
char f0copy[1000];
|
||||
char f2copy[1000];
|
||||
|
||||
strcpy(f0copy, f0);
|
||||
re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL;
|
||||
fixstr(f0copy);
|
||||
err = my_regcomp(&re, f0copy, opts, &my_charset_latin1);
|
||||
if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
|
||||
/* unexpected error or wrong error */
|
||||
len = my_regerror(err, &re, erbuf, sizeof(erbuf));
|
||||
fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
|
||||
line, type, eprint(err), len,
|
||||
(int) sizeof(erbuf), erbuf);
|
||||
status = 1;
|
||||
} else if (err == 0 && opt('C', f1)) {
|
||||
/* unexpected success */
|
||||
fprintf(stderr, "%d: %s should have given REG_%s\n",
|
||||
line, type, f2);
|
||||
status = 1;
|
||||
err = 1; /* so we won't try regexec */
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
my_regfree(&re);
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(f2copy, f2);
|
||||
fixstr(f2copy);
|
||||
|
||||
if (options('e', f1)®_STARTEND) {
|
||||
if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL)
|
||||
fprintf(stderr, "%d: bad STARTEND syntax\n", line);
|
||||
subs[0].rm_so = strchr(f2, '(') - f2 + 1;
|
||||
subs[0].rm_eo = strchr(f2, ')') - f2;
|
||||
}
|
||||
err = my_regexec(&re, f2copy, NSUBS, subs, options('e', f1));
|
||||
|
||||
if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
|
||||
/* unexpected error or wrong error */
|
||||
len = my_regerror(err, &re, erbuf, sizeof(erbuf));
|
||||
fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
|
||||
line, type, eprint(err), len,
|
||||
(int) sizeof(erbuf), erbuf);
|
||||
status = 1;
|
||||
} else if (err != 0) {
|
||||
/* nothing more to check */
|
||||
} else if (f3 == NULL) {
|
||||
/* unexpected success */
|
||||
fprintf(stderr, "%d: %s exec should have failed\n",
|
||||
line, type);
|
||||
status = 1;
|
||||
err = 1; /* just on principle */
|
||||
} else if (opts®_NOSUB) {
|
||||
/* nothing more to check */
|
||||
} else if ((grump = check(f2, subs[0], f3)) != NULL) {
|
||||
fprintf(stderr, "%d: %s %s\n", line, type, grump);
|
||||
status = 1;
|
||||
err = 1;
|
||||
}
|
||||
|
||||
if (err != 0 || f4 == NULL) {
|
||||
my_regfree(&re);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < NSHOULD; i++)
|
||||
should[i] = NULL;
|
||||
nshould = split(f4, should+1, NSHOULD-1, ",");
|
||||
if (nshould == 0) {
|
||||
nshould = 1;
|
||||
should[1] = (char*) "";
|
||||
}
|
||||
for (i = 1; i < NSUBS; i++) {
|
||||
grump = check(f2, subs[i], should[i]);
|
||||
if (grump != NULL) {
|
||||
fprintf(stderr, "%d: %s $%d %s\n", line,
|
||||
type, i, grump);
|
||||
status = 1;
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
|
||||
my_regfree(&re);
|
||||
}
|
||||
|
||||
/*
|
||||
- options - pick options out of a regression-test string
|
||||
== int options(int type, char *s);
|
||||
*/
|
||||
int
|
||||
options(type, s)
|
||||
int type; /* 'c' compile, 'e' exec */
|
||||
char *s;
|
||||
{
|
||||
register char *p;
|
||||
register int o = (type == 'c') ? copts : eopts;
|
||||
register const char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
|
||||
|
||||
for (p = s; *p != '\0'; p++)
|
||||
if (strchr(legal, *p) != NULL)
|
||||
switch (*p) {
|
||||
case 'b':
|
||||
o &= ~REG_EXTENDED;
|
||||
break;
|
||||
case 'i':
|
||||
o |= REG_ICASE;
|
||||
break;
|
||||
case 's':
|
||||
o |= REG_NOSUB;
|
||||
break;
|
||||
case 'n':
|
||||
o |= REG_NEWLINE;
|
||||
break;
|
||||
case 'm':
|
||||
o &= ~REG_EXTENDED;
|
||||
o |= REG_NOSPEC;
|
||||
break;
|
||||
case 'p':
|
||||
o |= REG_PEND;
|
||||
break;
|
||||
case '^':
|
||||
o |= REG_NOTBOL;
|
||||
break;
|
||||
case '$':
|
||||
o |= REG_NOTEOL;
|
||||
break;
|
||||
case '#':
|
||||
o |= REG_STARTEND;
|
||||
break;
|
||||
case 't': /* trace */
|
||||
o |= REG_TRACE;
|
||||
break;
|
||||
case 'l': /* force long representation */
|
||||
o |= REG_LARGE;
|
||||
break;
|
||||
case 'r': /* force backref use */
|
||||
o |= REG_BACKR;
|
||||
break;
|
||||
}
|
||||
return(o);
|
||||
}
|
||||
|
||||
/*
|
||||
- opt - is a particular option in a regression string?
|
||||
== int opt(int c, char *s);
|
||||
*/
|
||||
int /* predicate */
|
||||
opt(c, s)
|
||||
int c;
|
||||
char *s;
|
||||
{
|
||||
return(strchr(s, c) != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
- fixstr - transform magic characters in strings
|
||||
== void fixstr(register char *p);
|
||||
*/
|
||||
void
|
||||
fixstr(p)
|
||||
register char *p;
|
||||
{
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
for (; *p != '\0'; p++)
|
||||
if (*p == 'N')
|
||||
*p = '\n';
|
||||
else if (*p == 'T')
|
||||
*p = '\t';
|
||||
else if (*p == 'S')
|
||||
*p = ' ';
|
||||
else if (*p == 'Z')
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
- check - check a substring match
|
||||
== char *check(char *str, regmatch_t sub, char *should);
|
||||
*/
|
||||
char * /* NULL or complaint */
|
||||
check(str, sub, should)
|
||||
char *str;
|
||||
my_regmatch_t sub;
|
||||
char *should;
|
||||
{
|
||||
register int len;
|
||||
register int shlen;
|
||||
register char *p;
|
||||
static char grump[500];
|
||||
register char *at = NULL;
|
||||
|
||||
if (should != NULL && strcmp(should, "-") == 0)
|
||||
should = NULL;
|
||||
if (should != NULL && should[0] == '@') {
|
||||
at = should + 1;
|
||||
should = (char*) "";
|
||||
}
|
||||
|
||||
/* check rm_so and rm_eo for consistency */
|
||||
if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) ||
|
||||
(sub.rm_so != -1 && sub.rm_eo == -1) ||
|
||||
(sub.rm_so != -1 && sub.rm_so < 0) ||
|
||||
(sub.rm_eo != -1 && sub.rm_eo < 0) ) {
|
||||
sprintf(grump, "start %ld end %ld", (long)sub.rm_so,
|
||||
(long)sub.rm_eo);
|
||||
return(grump);
|
||||
}
|
||||
|
||||
/* check for no match */
|
||||
if (sub.rm_so == -1 && should == NULL)
|
||||
return(NULL);
|
||||
if (sub.rm_so == -1)
|
||||
return((char*) "did not match");
|
||||
|
||||
/* check for in range */
|
||||
if ((int) sub.rm_eo > (int) strlen(str)) {
|
||||
sprintf(grump, "start %ld end %ld, past end of string",
|
||||
(long)sub.rm_so, (long)sub.rm_eo);
|
||||
return(grump);
|
||||
}
|
||||
|
||||
len = (int)(sub.rm_eo - sub.rm_so);
|
||||
shlen = (int)strlen(should);
|
||||
p = str + sub.rm_so;
|
||||
|
||||
/* check for not supposed to match */
|
||||
if (should == NULL) {
|
||||
sprintf(grump, "matched `%.*s'", len, p);
|
||||
return(grump);
|
||||
}
|
||||
|
||||
/* check for wrong match */
|
||||
if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
|
||||
sprintf(grump, "matched `%.*s' instead", len, p);
|
||||
return(grump);
|
||||
}
|
||||
if (shlen > 0)
|
||||
return(NULL);
|
||||
|
||||
/* check null match in right place */
|
||||
if (at == NULL)
|
||||
return(NULL);
|
||||
shlen = strlen(at);
|
||||
if (shlen == 0)
|
||||
shlen = 1; /* force check for end-of-string */
|
||||
if (strncmp(p, at, shlen) != 0) {
|
||||
sprintf(grump, "matched null at `%.20s'", p);
|
||||
return(grump);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
- eprint - convert error number to name
|
||||
== static char *eprint(int err);
|
||||
*/
|
||||
static char *
|
||||
eprint(err)
|
||||
int err;
|
||||
{
|
||||
static char epbuf[100];
|
||||
size_t len;
|
||||
|
||||
len = my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf));
|
||||
assert(len <= sizeof(epbuf));
|
||||
return(epbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
- efind - convert error name to number
|
||||
== static int efind(char *name);
|
||||
*/
|
||||
static int
|
||||
efind(name)
|
||||
char *name;
|
||||
{
|
||||
static char efbuf[100];
|
||||
my_regex_t re;
|
||||
|
||||
sprintf(efbuf, "REG_%s", name);
|
||||
assert(strlen(efbuf) < sizeof(efbuf));
|
||||
re.re_endp = efbuf;
|
||||
(void) my_regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
|
||||
return(atoi(efbuf));
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
#ifndef _REGEX_H_
|
||||
#define _REGEX_H_ /* never again */
|
||||
/* ========= begin header generated by ./mkh ========= */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "m_ctype.h"
|
||||
|
||||
/* === regex2.h === */
|
||||
#ifdef _WIN64
|
||||
typedef __int64 regoff_t;
|
||||
#else
|
||||
typedef off_t regoff_t;
|
||||
#endif
|
||||
struct re_guts; /* none of your business :-) */
|
||||
typedef struct {
|
||||
int re_magic;
|
||||
size_t re_nsub; /* number of parenthesized subexpressions */
|
||||
const char *re_endp; /* end pointer for REG_PEND */
|
||||
struct re_guts *re_g; /* none of your business :-) */
|
||||
CHARSET_INFO *charset; /* For ctype things */
|
||||
} my_regex_t;
|
||||
typedef struct {
|
||||
regoff_t rm_so; /* start of match */
|
||||
regoff_t rm_eo; /* end of match */
|
||||
} my_regmatch_t;
|
||||
|
||||
|
||||
/* === regcomp.c === */
|
||||
extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset);
|
||||
#define REG_BASIC 0000
|
||||
#define REG_EXTENDED 0001
|
||||
#define REG_ICASE 0002
|
||||
#define REG_NOSUB 0004
|
||||
#define REG_NEWLINE 0010
|
||||
#define REG_NOSPEC 0020
|
||||
#define REG_PEND 0040
|
||||
#define REG_DUMP 0200
|
||||
|
||||
|
||||
/* === regerror.c === */
|
||||
#define REG_NOMATCH 1
|
||||
#define REG_BADPAT 2
|
||||
#define REG_ECOLLATE 3
|
||||
#define REG_ECTYPE 4
|
||||
#define REG_EESCAPE 5
|
||||
#define REG_ESUBREG 6
|
||||
#define REG_EBRACK 7
|
||||
#define REG_EPAREN 8
|
||||
#define REG_EBRACE 9
|
||||
#define REG_BADBR 10
|
||||
#define REG_ERANGE 11
|
||||
#define REG_ESPACE 12
|
||||
#define REG_BADRPT 13
|
||||
#define REG_EMPTY 14
|
||||
#define REG_ASSERT 15
|
||||
#define REG_INVARG 16
|
||||
#define REG_ATOI 255 /* convert name to number (!) */
|
||||
#define REG_ITOA 0400 /* convert number to name (!) */
|
||||
extern size_t my_regerror(int, const my_regex_t *, char *, size_t);
|
||||
|
||||
|
||||
/* === regexec.c === */
|
||||
extern int my_regexec(const my_regex_t *, const char *, size_t, my_regmatch_t [], int);
|
||||
#define REG_NOTBOL 00001
|
||||
#define REG_NOTEOL 00002
|
||||
#define REG_STARTEND 00004
|
||||
#define REG_TRACE 00400 /* tracing of execution */
|
||||
#define REG_LARGE 01000 /* force large representation */
|
||||
#define REG_BACKR 02000 /* force use of backref code */
|
||||
|
||||
|
||||
/* === regfree.c === */
|
||||
extern void my_regfree(my_regex_t *);
|
||||
|
||||
/* === reginit.c === */
|
||||
|
||||
extern void my_regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */
|
||||
extern void my_regex_end(void); /* If one wants a clean end */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* ========= end header generated by ./mkh ========= */
|
||||
#endif
|
||||
+1672
File diff suppressed because it is too large
Load Diff
+116
@@ -0,0 +1,116 @@
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
#include "my_regex.h"
|
||||
#include "utils.h"
|
||||
#include "regerror.ih"
|
||||
|
||||
/*
|
||||
= #define REG_NOMATCH 1
|
||||
= #define REG_BADPAT 2
|
||||
= #define REG_ECOLLATE 3
|
||||
= #define REG_ECTYPE 4
|
||||
= #define REG_EESCAPE 5
|
||||
= #define REG_ESUBREG 6
|
||||
= #define REG_EBRACK 7
|
||||
= #define REG_EPAREN 8
|
||||
= #define REG_EBRACE 9
|
||||
= #define REG_BADBR 10
|
||||
= #define REG_ERANGE 11
|
||||
= #define REG_ESPACE 12
|
||||
= #define REG_BADRPT 13
|
||||
= #define REG_EMPTY 14
|
||||
= #define REG_ASSERT 15
|
||||
= #define REG_INVARG 16
|
||||
= #define REG_ATOI 255 // convert name to number (!)
|
||||
= #define REG_ITOA 0400 // convert number to name (!)
|
||||
*/
|
||||
static struct rerr {
|
||||
int code;
|
||||
const char *name;
|
||||
const char *explain;
|
||||
} rerrs[] = {
|
||||
{REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
|
||||
{REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
|
||||
{REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
|
||||
{REG_ECTYPE, "REG_ECTYPE", "invalid character class"},
|
||||
{REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},
|
||||
{REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},
|
||||
{REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},
|
||||
{REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},
|
||||
{REG_EBRACE, "REG_EBRACE", "braces not balanced"},
|
||||
{REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},
|
||||
{REG_ERANGE, "REG_ERANGE", "invalid character range"},
|
||||
{REG_ESPACE, "REG_ESPACE", "out of memory"},
|
||||
{REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},
|
||||
{REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},
|
||||
{REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},
|
||||
{REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},
|
||||
{0, "", "*** unknown regexp error code ***"},
|
||||
};
|
||||
|
||||
/*
|
||||
- regerror - the interface to error numbers
|
||||
= extern size_t regerror(int, const regex_t *, char *, size_t);
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
size_t
|
||||
my_regerror(int errcode, const my_regex_t *preg, char *errbuf, size_t errbuf_size)
|
||||
{
|
||||
register struct rerr *r;
|
||||
register size_t len;
|
||||
register int target = errcode &~ REG_ITOA;
|
||||
register char *s;
|
||||
char convbuf[50];
|
||||
|
||||
if (errcode == REG_ATOI)
|
||||
s = regatoi(preg, convbuf);
|
||||
else {
|
||||
for (r = rerrs; r->code != 0; r++)
|
||||
if (r->code == target)
|
||||
break;
|
||||
|
||||
if (errcode®_ITOA) {
|
||||
if (r->code != 0)
|
||||
(void) strcpy(convbuf, r->name);
|
||||
else
|
||||
sprintf(convbuf, "REG_0x%x", target);
|
||||
assert(strlen(convbuf) < sizeof(convbuf));
|
||||
s = convbuf;
|
||||
} else
|
||||
s = (char*) r->explain;
|
||||
}
|
||||
|
||||
len = strlen(s) + 1;
|
||||
if (errbuf_size > 0) {
|
||||
if (errbuf_size > len)
|
||||
(void) strcpy(errbuf, s);
|
||||
else {
|
||||
(void) strncpy(errbuf, s, errbuf_size-1);
|
||||
errbuf[errbuf_size-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
/*
|
||||
- regatoi - internal routine to implement REG_ATOI
|
||||
== static char *regatoi(const regex_t *preg, char *localbuf);
|
||||
*/
|
||||
static char *
|
||||
regatoi(preg, localbuf)
|
||||
const my_regex_t *preg;
|
||||
char *localbuf;
|
||||
{
|
||||
register struct rerr *r;
|
||||
for (r = rerrs; r->code != 0; r++)
|
||||
if (strcmp(r->name, preg->re_endp) == 0)
|
||||
break;
|
||||
if (r->code == 0)
|
||||
return((char*) "0");
|
||||
|
||||
sprintf(localbuf, "%d", r->code);
|
||||
return(localbuf);
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* First, the stuff that ends up in the outside-world include file
|
||||
= typedef off_t regoff_t;
|
||||
= typedef struct {
|
||||
= int re_magic;
|
||||
= size_t re_nsub; // number of parenthesized subexpressions
|
||||
= const char *re_endp; // end pointer for REG_PEND
|
||||
= struct re_guts *re_g; // none of your business :-)
|
||||
= } regex_t;
|
||||
= typedef struct {
|
||||
= regoff_t rm_so; // start of match
|
||||
= regoff_t rm_eo; // end of match
|
||||
= } regmatch_t;
|
||||
*/
|
||||
/*
|
||||
* internals of regex_t
|
||||
*/
|
||||
#ifndef __regex2_h__
|
||||
#define __regex2_h__
|
||||
|
||||
#define MAGIC1 ((('r'^0200)<<8) | 'e')
|
||||
|
||||
/*
|
||||
* The internal representation is a *strip*, a sequence of
|
||||
* operators ending with an endmarker. (Some terminology etc. is a
|
||||
* historical relic of earlier versions which used multiple strips.)
|
||||
* Certain oddities in the representation are there to permit running
|
||||
* the machinery backwards; in particular, any deviation from sequential
|
||||
* flow must be marked at both its source and its destination. Some
|
||||
* fine points:
|
||||
*
|
||||
* - OPLUS_ and O_PLUS are *inside* the loop they create.
|
||||
* - OQUEST_ and O_QUEST are *outside* the bypass they create.
|
||||
* - OCH_ and O_CH are *outside* the multi-way branch they create, while
|
||||
* OOR1 and OOR2 are respectively the end and the beginning of one of
|
||||
* the branches. Note that there is an implicit OOR2 following OCH_
|
||||
* and an implicit OOR1 preceding O_CH.
|
||||
*
|
||||
* In state representations, an operator's bit is on to signify a state
|
||||
* immediately *preceding* "execution" of that operator.
|
||||
*/
|
||||
typedef unsigned long sop; /* strip operator */
|
||||
typedef long sopno;
|
||||
#define OPRMASK 0xf8000000
|
||||
#define OPDMASK 0x07ffffff
|
||||
#define OPSHIFT ((unsigned long)27)
|
||||
#define OP(n) ((unsigned long) ((n)&OPRMASK))
|
||||
#define OPND(n) ((unsigned long) ((n)&OPDMASK))
|
||||
#define SOP(op, opnd) (unsigned long) ((op)|(opnd))
|
||||
#define OSHIFT(A) ((unsigned long) (A) << OPSHIFT)
|
||||
/* operators meaning operand */
|
||||
/* (back, fwd are offsets) */
|
||||
#define OEND OSHIFT(1) /* endmarker - */
|
||||
#define OCHAR OSHIFT(2) /* character unsigned char */
|
||||
#define OBOL OSHIFT(3) /* left anchor - */
|
||||
#define OEOL OSHIFT(4) /* right anchor - */
|
||||
#define OANY OSHIFT(5) /* . - */
|
||||
#define OANYOF OSHIFT(6) /* [...] set number */
|
||||
#define OBACK_ OSHIFT(7) /* begin \d paren number */
|
||||
#define O_BACK OSHIFT(8) /* end \d paren number */
|
||||
#define OPLUS_ OSHIFT(9) /* + prefix fwd to suffix */
|
||||
#define O_PLUS OSHIFT(10) /* + suffix back to prefix */
|
||||
#define OQUEST_ OSHIFT(11) /* ? prefix fwd to suffix */
|
||||
#define O_QUEST OSHIFT(12) /* ? suffix back to prefix */
|
||||
#define OLPAREN OSHIFT(13) /* ( fwd to ) */
|
||||
#define ORPAREN OSHIFT(14) /* ) back to ( */
|
||||
#define OCH_ OSHIFT(15) /* begin choice fwd to OOR2 */
|
||||
#define OOR1 OSHIFT(16) /* | pt. 1 back to OOR1 or OCH_ */
|
||||
#define OOR2 OSHIFT(17) /* | pt. 2 fwd to OOR2 or O_CH */
|
||||
#define O_CH OSHIFT(18) /* end choice back to OOR1 */
|
||||
#define OBOW OSHIFT(19) /* begin word - */
|
||||
#define OEOW OSHIFT(20) /* end word - */
|
||||
|
||||
/*
|
||||
* Structure for [] character-set representation. Character sets are
|
||||
* done as bit vectors, grouped 8 to a byte vector for compactness.
|
||||
* The individual set therefore has both a pointer to the byte vector
|
||||
* and a mask to pick out the relevant bit of each byte. A hash code
|
||||
* simplifies testing whether two sets could be identical.
|
||||
*
|
||||
* This will get trickier for multicharacter collating elements. As
|
||||
* preliminary hooks for dealing with such things, we also carry along
|
||||
* a string of multi-character elements, and decide the size of the
|
||||
* vectors at run time.
|
||||
*/
|
||||
#ifdef __WIN__
|
||||
typedef unsigned char uch ;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uch *ptr; /* -> uch [csetsize] */
|
||||
uch mask; /* bit within array */
|
||||
uch hash; /* hash code */
|
||||
size_t smultis;
|
||||
char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
|
||||
} cset;
|
||||
/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
|
||||
#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (uch) (c))
|
||||
#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (uch)(c))
|
||||
#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
|
||||
#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
|
||||
#define MCsub(p, cs, cp) mcsub(p, cs, cp)
|
||||
#define MCin(p, cs, cp) mcin(p, cs, cp)
|
||||
|
||||
/* stuff for character categories */
|
||||
typedef unsigned char cat_t;
|
||||
|
||||
/*
|
||||
* main compiled-expression structure
|
||||
*/
|
||||
struct re_guts {
|
||||
int magic;
|
||||
# define MAGIC2 ((('R'^0200)<<8)|'E')
|
||||
sop *strip; /* malloced area for strip */
|
||||
int csetsize; /* number of bits in a cset vector */
|
||||
int ncsets; /* number of csets in use */
|
||||
cset *sets; /* -> cset [ncsets] */
|
||||
uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
|
||||
int cflags; /* copy of regcomp() cflags argument */
|
||||
sopno nstates; /* = number of sops */
|
||||
sopno firststate; /* the initial OEND (normally 0) */
|
||||
sopno laststate; /* the final OEND */
|
||||
int iflags; /* internal flags */
|
||||
# define USEBOL 01 /* used ^ */
|
||||
# define USEEOL 02 /* used $ */
|
||||
# define BAD 04 /* something wrong */
|
||||
int nbol; /* number of ^ used */
|
||||
int neol; /* number of $ used */
|
||||
int ncategories; /* how many character categories */
|
||||
cat_t *categories; /* ->catspace[-CHAR_MIN] */
|
||||
char *must; /* match must contain this string */
|
||||
int mlen; /* length of must */
|
||||
size_t nsub; /* copy of re_nsub */
|
||||
int backrefs; /* does it use back references? */
|
||||
sopno nplus; /* how deep does it nest +s? */
|
||||
/* catspace must be last */
|
||||
cat_t catspace[1]; /* actually [NC] */
|
||||
};
|
||||
|
||||
/* misc utilities */
|
||||
#undef OUT /* May be defined in windows */
|
||||
#define OUT (CHAR_MAX+1) /* a non-character value */
|
||||
#define ISWORD(s,c) (my_isalnum(s,c) || (c) == '_')
|
||||
|
||||
#endif /* __regex2_h__ */
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* the outer shell of regexec()
|
||||
*
|
||||
* This file includes engine.c *twice*, after muchos fiddling with the
|
||||
* macros that code uses. This lets the same code operate on two different
|
||||
* representations for state sets.
|
||||
*/
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
#ifdef __WIN__
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#include "my_regex.h"
|
||||
#include "utils.h"
|
||||
#include "regex2.h"
|
||||
|
||||
/* for use in asserts */
|
||||
#define nope 0
|
||||
|
||||
/* macros for manipulating states, small version */
|
||||
#define states long
|
||||
#define states1 long /* for later use in regexec() decision. Ensure Win64 definition is correct.*/
|
||||
#define CLEAR(v) ((v) = 0)
|
||||
#define SET0(v, n) ((v) &= ~((states) 1 << (n)))
|
||||
#define SET1(v, n) ((v) |= (states) 1 << (n))
|
||||
#define ISSET(v, n) ((v) & ((states) 1 << (n)))
|
||||
#define ASSIGN(d, s) ((d) = (s))
|
||||
#define EQ(a, b) ((a) == (b))
|
||||
#define STATEVARS int dummy /* dummy version */
|
||||
#define STATESETUP(m, n) /* nothing */
|
||||
#define STATETEARDOWN(m) /* nothing */
|
||||
#define SETUP(v) ((v) = 0)
|
||||
#define onestate long /* Changed from int by Monty */
|
||||
#define INIT(o, n) ((o) = (unsigned states)1 << (n))
|
||||
#define INC(o) ((o) <<= 1)
|
||||
#define ISSTATEIN(v, o) ((v) & (o))
|
||||
/* some abbreviations; note that some of these know variable names! */
|
||||
/* do "if I'm here, I can also be there" etc without branches */
|
||||
#define FWD(dst, src, n) ((dst) |= ((unsigned states)(src)&(here)) << (n))
|
||||
#define BACK(dst, src, n) ((dst) |= ((unsigned states)(src)&(here)) >> (n))
|
||||
#define ISSETBACK(v, n) ((v) & ((unsigned states)here >> (n)))
|
||||
/* function names */
|
||||
#define SNAMES /* engine.c looks after details */
|
||||
|
||||
#include "engine.c"
|
||||
|
||||
/* now undo things */
|
||||
#undef states
|
||||
#undef CLEAR
|
||||
#undef SET0
|
||||
#undef SET1
|
||||
#undef ISSET
|
||||
#undef ASSIGN
|
||||
#undef EQ
|
||||
#undef STATEVARS
|
||||
#undef STATESETUP
|
||||
#undef STATETEARDOWN
|
||||
#undef SETUP
|
||||
#undef onestate
|
||||
#undef INIT
|
||||
#undef INC
|
||||
#undef ISSTATEIN
|
||||
#undef FWD
|
||||
#undef BACK
|
||||
#undef ISSETBACK
|
||||
#undef SNAMES
|
||||
|
||||
/* macros for manipulating states, large version */
|
||||
#define states char *
|
||||
#define CLEAR(v) memset(v, 0, m->g->nstates)
|
||||
#define SET0(v, n) ((v)[n] = 0)
|
||||
#define SET1(v, n) ((v)[n] = 1)
|
||||
#define ISSET(v, n) ((v)[n])
|
||||
#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
|
||||
#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
|
||||
#define STATEVARS int vn; char *space
|
||||
#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
|
||||
if ((m)->space == NULL) return(REG_ESPACE); \
|
||||
(m)->vn = 0; }
|
||||
#define STATETEARDOWN(m) { free((m)->space); }
|
||||
#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
|
||||
#define onestate int
|
||||
#define INIT(o, n) ((o) = (n))
|
||||
#define INC(o) ((o)++)
|
||||
#define ISSTATEIN(v, o) ((v)[o])
|
||||
/* some abbreviations; note that some of these know variable names! */
|
||||
/* do "if I'm here, I can also be there" etc without branches */
|
||||
#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
|
||||
#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
|
||||
#define ISSETBACK(v, n) ((v)[here - (n)])
|
||||
/* function names */
|
||||
#define LNAMES /* flag */
|
||||
|
||||
#include "engine.c"
|
||||
|
||||
/*
|
||||
- regexec - interface for matching
|
||||
= extern int regexec(const regex_t *, const char *, size_t, \
|
||||
= regmatch_t [], int);
|
||||
= #define REG_NOTBOL 00001
|
||||
= #define REG_NOTEOL 00002
|
||||
= #define REG_STARTEND 00004
|
||||
= #define REG_TRACE 00400 // tracing of execution
|
||||
= #define REG_LARGE 01000 // force large representation
|
||||
= #define REG_BACKR 02000 // force use of backref code
|
||||
*
|
||||
* We put this here so we can exploit knowledge of the state representation
|
||||
* when choosing which matcher to call. Also, by this point the matchers
|
||||
* have been prototyped.
|
||||
*/
|
||||
int /* 0 success, REG_NOMATCH failure */
|
||||
my_regexec(preg, str, nmatch, pmatch, eflags)
|
||||
const my_regex_t *preg;
|
||||
const char *str;
|
||||
size_t nmatch;
|
||||
my_regmatch_t pmatch[];
|
||||
int eflags;
|
||||
{
|
||||
register struct re_guts *g = preg->re_g;
|
||||
#ifdef REDEBUG
|
||||
# define GOODFLAGS(f) (f)
|
||||
#else
|
||||
# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
|
||||
#endif
|
||||
|
||||
if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
|
||||
return(REG_BADPAT);
|
||||
assert(!(g->iflags&BAD));
|
||||
if (g->iflags&BAD) /* backstop for no-debug case */
|
||||
return(REG_BADPAT);
|
||||
eflags = GOODFLAGS(eflags);
|
||||
|
||||
if ((size_t) g->nstates <= CHAR_BIT*sizeof(states1) &&
|
||||
!(eflags®_LARGE))
|
||||
return(smatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
|
||||
else
|
||||
return(lmatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
|
||||
}
|
||||
+1348
File diff suppressed because it is too large
Load Diff
+38
@@ -0,0 +1,38 @@
|
||||
#include <my_global.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "my_regex.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "regex2.h"
|
||||
|
||||
/*
|
||||
- regfree - free everything
|
||||
= extern void regfree(regex_t *);
|
||||
*/
|
||||
void
|
||||
my_regfree(preg)
|
||||
my_regex_t *preg;
|
||||
{
|
||||
register struct re_guts *g;
|
||||
|
||||
if (preg->re_magic != MAGIC1) /* oops */
|
||||
return; /* nice to complain, but hard */
|
||||
|
||||
g = preg->re_g;
|
||||
if (g == NULL || g->magic != MAGIC2) /* oops again */
|
||||
return;
|
||||
preg->re_magic = 0; /* mark it invalid */
|
||||
g->magic = 0; /* mark it invalid */
|
||||
|
||||
if (g->strip != NULL)
|
||||
free((char *)g->strip);
|
||||
if (g->sets != NULL)
|
||||
free((char *)g->sets);
|
||||
if (g->setbits != NULL)
|
||||
free((char *)g->setbits);
|
||||
if (g->must != NULL)
|
||||
free(g->must);
|
||||
free((char *)g);
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/* Init cclasses array from ctypes */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
#include "cclass.h"
|
||||
|
||||
static my_bool regex_inited=0;
|
||||
|
||||
void my_regex_init(CHARSET_INFO *cs)
|
||||
{
|
||||
char buff[CCLASS_LAST][256];
|
||||
int count[CCLASS_LAST];
|
||||
uint i;
|
||||
|
||||
if (!regex_inited)
|
||||
{
|
||||
regex_inited=1;
|
||||
bzero((uchar*) &count,sizeof(count));
|
||||
|
||||
for (i=1 ; i<= 255; i++)
|
||||
{
|
||||
if (my_isalnum(cs,i))
|
||||
buff[CCLASS_ALNUM][count[CCLASS_ALNUM]++]=(char) i;
|
||||
if (my_isalpha(cs,i))
|
||||
buff[CCLASS_ALPHA][count[CCLASS_ALPHA]++]=(char) i;
|
||||
if (my_iscntrl(cs,i))
|
||||
buff[CCLASS_CNTRL][count[CCLASS_CNTRL]++]=(char) i;
|
||||
if (my_isdigit(cs,i))
|
||||
buff[CCLASS_DIGIT][count[CCLASS_DIGIT]++]=(char) i;
|
||||
if (my_isgraph(cs,i))
|
||||
buff[CCLASS_GRAPH][count[CCLASS_GRAPH]++]=(char) i;
|
||||
if (my_islower(cs,i))
|
||||
buff[CCLASS_LOWER][count[CCLASS_LOWER]++]=(char) i;
|
||||
if (my_isprint(cs,i))
|
||||
buff[CCLASS_PRINT][count[CCLASS_PRINT]++]=(char) i;
|
||||
if (my_ispunct(cs,i))
|
||||
buff[CCLASS_PUNCT][count[CCLASS_PUNCT]++]=(char) i;
|
||||
if (my_isspace(cs,i))
|
||||
buff[CCLASS_SPACE][count[CCLASS_SPACE]++]=(char) i;
|
||||
if (my_isupper(cs,i))
|
||||
buff[CCLASS_UPPER][count[CCLASS_UPPER]++]=(char) i;
|
||||
if (my_isxdigit(cs,i))
|
||||
buff[CCLASS_XDIGIT][count[CCLASS_XDIGIT]++]=(char) i;
|
||||
}
|
||||
buff[CCLASS_BLANK][0]=' ';
|
||||
buff[CCLASS_BLANK][1]='\t';
|
||||
count[CCLASS_BLANK]=2;
|
||||
for (i=0; i < CCLASS_LAST ; i++)
|
||||
{
|
||||
char *tmp=(char*) malloc(count[i]+1);
|
||||
if (!tmp)
|
||||
{
|
||||
/*
|
||||
This is very unlikely to happen as this function is called once
|
||||
at program startup
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"Fatal error: Can't allocate memory in regex_init\n");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(tmp,buff[i],count[i]*sizeof(char));
|
||||
tmp[count[i]]=0;
|
||||
cclasses[i].chars=tmp;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void my_regex_end()
|
||||
{
|
||||
if (regex_inited)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < CCLASS_LAST ; i++)
|
||||
free((char*) cclasses[i].chars);
|
||||
regex_inited=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+316
@@ -0,0 +1,316 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
- split - divide a string into fields, like awk split()
|
||||
= int split(char *string, char *fields[], int nfields, char *sep);
|
||||
*/
|
||||
int /* number of fields, including overflow */
|
||||
split(string, fields, nfields, sep)
|
||||
char *string;
|
||||
char *fields[]; /* list is not NULL-terminated */
|
||||
int nfields; /* number of entries available in fields[] */
|
||||
char *sep; /* "" white, "c" single char, "ab" [ab]+ */
|
||||
{
|
||||
register char *p = string;
|
||||
register char c; /* latest character */
|
||||
register char sepc = sep[0];
|
||||
register char sepc2;
|
||||
register int fn;
|
||||
register char **fp = fields;
|
||||
register char *sepp;
|
||||
register int trimtrail;
|
||||
|
||||
/* white space */
|
||||
if (sepc == '\0') {
|
||||
while ((c = *p++) == ' ' || c == '\t')
|
||||
continue;
|
||||
p--;
|
||||
trimtrail = 1;
|
||||
sep = (char*) " \t"; /* note, code below knows this is 2 long */
|
||||
sepc = ' ';
|
||||
} else
|
||||
trimtrail = 0;
|
||||
sepc2 = sep[1]; /* now we can safely pick this up */
|
||||
|
||||
/* catch empties */
|
||||
if (*p == '\0')
|
||||
return(0);
|
||||
|
||||
/* single separator */
|
||||
if (sepc2 == '\0') {
|
||||
fn = nfields;
|
||||
for (;;) {
|
||||
*fp++ = p;
|
||||
fn--;
|
||||
if (fn == 0)
|
||||
break;
|
||||
while ((c = *p++) != sepc)
|
||||
if (c == '\0')
|
||||
return(nfields - fn);
|
||||
*(p-1) = '\0';
|
||||
}
|
||||
/* we have overflowed the fields vector -- just count them */
|
||||
fn = nfields;
|
||||
for (;;) {
|
||||
while ((c = *p++) != sepc)
|
||||
if (c == '\0')
|
||||
return(fn);
|
||||
fn++;
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
/* two separators */
|
||||
if (sep[2] == '\0') {
|
||||
fn = nfields;
|
||||
for (;;) {
|
||||
*fp++ = p;
|
||||
fn--;
|
||||
while ((c = *p++) != sepc && c != sepc2)
|
||||
if (c == '\0') {
|
||||
if (trimtrail && **(fp-1) == '\0')
|
||||
fn++;
|
||||
return(nfields - fn);
|
||||
}
|
||||
if (fn == 0)
|
||||
break;
|
||||
*(p-1) = '\0';
|
||||
while ((c = *p++) == sepc || c == sepc2)
|
||||
continue;
|
||||
p--;
|
||||
}
|
||||
/* we have overflowed the fields vector -- just count them */
|
||||
fn = nfields;
|
||||
while (c != '\0') {
|
||||
while ((c = *p++) == sepc || c == sepc2)
|
||||
continue;
|
||||
p--;
|
||||
fn++;
|
||||
while ((c = *p++) != '\0' && c != sepc && c != sepc2)
|
||||
continue;
|
||||
}
|
||||
/* might have to trim trailing white space */
|
||||
if (trimtrail) {
|
||||
p--;
|
||||
while ((c = *--p) == sepc || c == sepc2)
|
||||
continue;
|
||||
p++;
|
||||
if (*p != '\0') {
|
||||
if (fn == nfields+1)
|
||||
*p = '\0';
|
||||
fn--;
|
||||
}
|
||||
}
|
||||
return(fn);
|
||||
}
|
||||
|
||||
/* n separators */
|
||||
fn = 0;
|
||||
for (;;) {
|
||||
if (fn < nfields)
|
||||
*fp++ = p;
|
||||
fn++;
|
||||
for (;;) {
|
||||
c = *p++;
|
||||
if (c == '\0')
|
||||
return(fn);
|
||||
sepp = sep;
|
||||
while ((sepc = *sepp++) != '\0' && sepc != c)
|
||||
continue;
|
||||
if (sepc != '\0') /* it was a separator */
|
||||
break;
|
||||
}
|
||||
if (fn < nfields)
|
||||
*(p-1) = '\0';
|
||||
for (;;) {
|
||||
c = *p++;
|
||||
sepp = sep;
|
||||
while ((sepc = *sepp++) != '\0' && sepc != c)
|
||||
continue;
|
||||
if (sepc == '\0') /* it wasn't a separator */
|
||||
break;
|
||||
}
|
||||
p--;
|
||||
}
|
||||
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
#ifdef TEST_SPLIT
|
||||
|
||||
|
||||
/*
|
||||
* test program
|
||||
* pgm runs regression
|
||||
* pgm sep splits stdin lines by sep
|
||||
* pgm str sep splits str by sep
|
||||
* pgm str sep n splits str by sep n times
|
||||
*/
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char buf[512];
|
||||
register int n;
|
||||
# define MNF 10
|
||||
char *fields[MNF];
|
||||
|
||||
if (argc > 4)
|
||||
for (n = atoi(argv[3]); n > 0; n--) {
|
||||
(void) strcpy(buf, argv[1]);
|
||||
}
|
||||
else if (argc > 3)
|
||||
for (n = atoi(argv[3]); n > 0; n--) {
|
||||
(void) strcpy(buf, argv[1]);
|
||||
(void) split(buf, fields, MNF, argv[2]);
|
||||
}
|
||||
else if (argc > 2)
|
||||
dosplit(argv[1], argv[2]);
|
||||
else if (argc > 1)
|
||||
while (fgets(buf, sizeof(buf), stdin) != NULL) {
|
||||
buf[strlen(buf)-1] = '\0'; /* stomp newline */
|
||||
dosplit(buf, argv[1]);
|
||||
}
|
||||
else
|
||||
regress();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
dosplit(string, seps)
|
||||
char *string;
|
||||
char *seps;
|
||||
{
|
||||
# define NF 5
|
||||
char *fields[NF];
|
||||
register int nf;
|
||||
|
||||
nf = split(string, fields, NF, seps);
|
||||
print(nf, NF, fields);
|
||||
}
|
||||
|
||||
print(nf, nfp, fields)
|
||||
int nf;
|
||||
int nfp;
|
||||
char *fields[];
|
||||
{
|
||||
register int fn;
|
||||
register int bound;
|
||||
|
||||
bound = (nf > nfp) ? nfp : nf;
|
||||
printf("%d:\t", nf);
|
||||
for (fn = 0; fn < bound; fn++)
|
||||
printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n");
|
||||
}
|
||||
|
||||
#define RNF 5 /* some table entries know this */
|
||||
struct {
|
||||
char *str;
|
||||
char *seps;
|
||||
int nf;
|
||||
char *fi[RNF];
|
||||
} tests[] = {
|
||||
"", " ", 0, { "" },
|
||||
" ", " ", 2, { "", "" },
|
||||
"x", " ", 1, { "x" },
|
||||
"xy", " ", 1, { "xy" },
|
||||
"x y", " ", 2, { "x", "y" },
|
||||
"abc def g ", " ", 5, { "abc", "def", "", "g", "" },
|
||||
" a bcd", " ", 4, { "", "", "a", "bcd" },
|
||||
"a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" },
|
||||
" a b c d ", " ", 6, { "", "a", "b", "c", "d " },
|
||||
|
||||
"", " _", 0, { "" },
|
||||
" ", " _", 2, { "", "" },
|
||||
"x", " _", 1, { "x" },
|
||||
"x y", " _", 2, { "x", "y" },
|
||||
"ab _ cd", " _", 2, { "ab", "cd" },
|
||||
" a_b c ", " _", 5, { "", "a", "b", "c", "" },
|
||||
"a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" },
|
||||
" a b c d ", " _", 6, { "", "a", "b", "c", "d " },
|
||||
|
||||
"", " _~", 0, { "" },
|
||||
" ", " _~", 2, { "", "" },
|
||||
"x", " _~", 1, { "x" },
|
||||
"x y", " _~", 2, { "x", "y" },
|
||||
"ab _~ cd", " _~", 2, { "ab", "cd" },
|
||||
" a_b c~", " _~", 5, { "", "a", "b", "c", "" },
|
||||
"a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" },
|
||||
"~a b c d ", " _~", 6, { "", "a", "b", "c", "d " },
|
||||
|
||||
"", " _~-", 0, { "" },
|
||||
" ", " _~-", 2, { "", "" },
|
||||
"x", " _~-", 1, { "x" },
|
||||
"x y", " _~-", 2, { "x", "y" },
|
||||
"ab _~- cd", " _~-", 2, { "ab", "cd" },
|
||||
" a_b c~", " _~-", 5, { "", "a", "b", "c", "" },
|
||||
"a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" },
|
||||
"~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " },
|
||||
|
||||
"", " ", 0, { "" },
|
||||
" ", " ", 2, { "", "" },
|
||||
"x", " ", 1, { "x" },
|
||||
"xy", " ", 1, { "xy" },
|
||||
"x y", " ", 2, { "x", "y" },
|
||||
"abc def g ", " ", 4, { "abc", "def", "g", "" },
|
||||
" a bcd", " ", 3, { "", "a", "bcd" },
|
||||
"a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" },
|
||||
" a b c d ", " ", 6, { "", "a", "b", "c", "d " },
|
||||
|
||||
"", "", 0, { "" },
|
||||
" ", "", 0, { "" },
|
||||
"x", "", 1, { "x" },
|
||||
"xy", "", 1, { "xy" },
|
||||
"x y", "", 2, { "x", "y" },
|
||||
"abc def g ", "", 3, { "abc", "def", "g" },
|
||||
"\t a bcd", "", 2, { "a", "bcd" },
|
||||
" a \tb\t c ", "", 3, { "a", "b", "c" },
|
||||
"a b c d e ", "", 5, { "a", "b", "c", "d", "e" },
|
||||
"a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" },
|
||||
" a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " },
|
||||
|
||||
NULL, NULL, 0, { NULL },
|
||||
};
|
||||
|
||||
regress()
|
||||
{
|
||||
char buf[512];
|
||||
register int n;
|
||||
char *fields[RNF+1];
|
||||
register int nf;
|
||||
register int i;
|
||||
register int printit;
|
||||
register char *f;
|
||||
|
||||
for (n = 0; tests[n].str != NULL; n++) {
|
||||
(void) strcpy(buf, tests[n].str);
|
||||
fields[RNF] = NULL;
|
||||
nf = split(buf, fields, RNF, tests[n].seps);
|
||||
printit = 0;
|
||||
if (nf != tests[n].nf) {
|
||||
printf("split `%s' by `%s' gave %d fields, not %d\n",
|
||||
tests[n].str, tests[n].seps, nf, tests[n].nf);
|
||||
printit = 1;
|
||||
} else if (fields[RNF] != NULL) {
|
||||
printf("split() went beyond array end\n");
|
||||
printit = 1;
|
||||
} else {
|
||||
for (i = 0; i < nf && i < RNF; i++) {
|
||||
f = fields[i];
|
||||
if (f == NULL)
|
||||
f = "(NULL)";
|
||||
if (strcmp(f, tests[n].fi[i]) != 0) {
|
||||
printf("split `%s' by `%s', field %d is `%s', not `%s'\n",
|
||||
tests[n].str, tests[n].seps,
|
||||
i, fields[i], tests[n].fi[i]);
|
||||
printit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printit)
|
||||
print(nf, RNF, fields);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
/* utility definitions */
|
||||
#ifdef _POSIX2_RE_DUP_MAX
|
||||
#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */
|
||||
#else
|
||||
#define DUPMAX 255
|
||||
#endif
|
||||
#define RE_INFINITY (DUPMAX + 1)
|
||||
#define NC (CHAR_MAX - CHAR_MIN + 1)
|
||||
typedef unsigned char uch;
|
||||
|
||||
/* switch off assertions (if not already off) if no REDEBUG */
|
||||
#ifndef REDEBUG
|
||||
#ifndef NDEBUG
|
||||
#define NDEBUG /* no assertions please */
|
||||
#endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/* for old systems with bcopy() but no memmove() */
|
||||
#ifdef USEBCOPY
|
||||
#define memmove(d, s, c) bcopy(s, d, c)
|
||||
#endif
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL buffer header defines input and output buffers to simulate streaming
|
||||
* with SSL types and sockets
|
||||
*/
|
||||
|
||||
#ifndef yaSSL_BUFFER_HPP
|
||||
#define yaSSL_BUFFER_HPP
|
||||
|
||||
#include <assert.h> // assert
|
||||
#include "yassl_types.hpp" // ysDelete
|
||||
#include "memory.hpp" // mySTL::auto_ptr
|
||||
#include STL_ALGORITHM_FILE
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// disable truncated debug symbols
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned int uint;
|
||||
const uint AUTO = 0xFEEDBEEF;
|
||||
|
||||
|
||||
// Checking Policy should implement a check function that tests whether the
|
||||
// index is within the size limit of the array
|
||||
struct Check {
|
||||
void check(uint i, uint limit);
|
||||
};
|
||||
|
||||
|
||||
struct NoCheck {
|
||||
void check(uint, uint);
|
||||
};
|
||||
|
||||
/* input_buffer operates like a smart c style array with a checking option,
|
||||
* meant to be read from through [] with AUTO index or read().
|
||||
* Should only write to at/near construction with assign() or raw (e.g., recv)
|
||||
* followed by add_size with the number of elements added by raw write.
|
||||
*
|
||||
* Not using vector because need checked []access, offset, and the ability to
|
||||
* write to the buffer bulk wise and have the correct size
|
||||
*/
|
||||
|
||||
class input_buffer : public Check {
|
||||
uint size_; // number of elements in buffer
|
||||
uint current_; // current offset position in buffer
|
||||
byte* buffer_; // storage for buffer
|
||||
byte* end_; // end of storage marker
|
||||
public:
|
||||
input_buffer();
|
||||
|
||||
explicit input_buffer(uint s);
|
||||
|
||||
// with assign
|
||||
input_buffer(uint s, const byte* t, uint len);
|
||||
|
||||
~input_buffer();
|
||||
|
||||
// users can pass defualt zero length buffer and then allocate
|
||||
void allocate(uint s);
|
||||
|
||||
// for passing to raw writing functions at beginning, then use add_size
|
||||
byte* get_buffer() const;
|
||||
|
||||
// after a raw write user can set new size
|
||||
// if you know the size before the write use assign()
|
||||
void add_size(uint i);
|
||||
|
||||
uint get_capacity() const;
|
||||
|
||||
uint get_current() const;
|
||||
|
||||
uint get_size() const;
|
||||
|
||||
uint get_remaining() const;
|
||||
|
||||
void set_current(uint i);
|
||||
|
||||
// read only access through [], advance current
|
||||
// user passes in AUTO index for ease of use
|
||||
const byte& operator[](uint i);
|
||||
|
||||
// end of input test
|
||||
bool eof();
|
||||
|
||||
// peek ahead
|
||||
byte peek() const;
|
||||
|
||||
// write function, should use at/near construction
|
||||
void assign(const byte* t, uint s);
|
||||
|
||||
// use read to query input, adjusts current
|
||||
void read(byte* dst, uint length);
|
||||
|
||||
private:
|
||||
input_buffer(const input_buffer&); // hide copy
|
||||
input_buffer& operator=(const input_buffer&); // and assign
|
||||
};
|
||||
|
||||
|
||||
/* output_buffer operates like a smart c style array with a checking option.
|
||||
* Meant to be written to through [] with AUTO index or write().
|
||||
* Size (current) counter increases when written to. Can be constructed with
|
||||
* zero length buffer but be sure to allocate before first use.
|
||||
* Don't use add write for a couple bytes, use [] instead, way less overhead.
|
||||
*
|
||||
* Not using vector because need checked []access and the ability to
|
||||
* write to the buffer bulk wise and retain correct size
|
||||
*/
|
||||
class output_buffer : public Check {
|
||||
uint current_; // current offset and elements in buffer
|
||||
byte* buffer_; // storage for buffer
|
||||
byte* end_; // end of storage marker
|
||||
public:
|
||||
// default
|
||||
output_buffer();
|
||||
|
||||
// with allocate
|
||||
explicit output_buffer(uint s);
|
||||
|
||||
// with assign
|
||||
output_buffer(uint s, const byte* t, uint len);
|
||||
|
||||
~output_buffer();
|
||||
|
||||
uint get_size() const;
|
||||
|
||||
uint get_capacity() const;
|
||||
|
||||
void set_current(uint c);
|
||||
|
||||
// users can pass defualt zero length buffer and then allocate
|
||||
void allocate(uint s);
|
||||
|
||||
// for passing to reading functions when finished
|
||||
const byte* get_buffer() const;
|
||||
|
||||
// allow write access through [], update current
|
||||
// user passes in AUTO as index for ease of use
|
||||
byte& operator[](uint i);
|
||||
|
||||
// end of output test
|
||||
bool eof();
|
||||
|
||||
void write(const byte* t, uint s);
|
||||
|
||||
private:
|
||||
output_buffer(const output_buffer&); // hide copy
|
||||
output_buffer& operator=(const output_buffer&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// turn delete an incomplete type into comipler error instead of warning
|
||||
template <typename T>
|
||||
inline void checked_delete(T* p)
|
||||
{
|
||||
typedef char complete_type[sizeof(T) ? 1 : -1];
|
||||
(void)sizeof(complete_type);
|
||||
ysDelete(p);
|
||||
}
|
||||
|
||||
|
||||
// checked delete functor increases effeciency, no indirection on function call
|
||||
// sets pointer to zero so safe for std conatiners
|
||||
struct del_ptr_zero
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(T*& p) const
|
||||
{
|
||||
T* tmp = 0;
|
||||
STL::swap(tmp, p);
|
||||
checked_delete(tmp);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_BUUFER_HPP
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* The certificate wrapper header defines certificate management functions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_CERT_WRAPPER_HPP
|
||||
#define yaSSL_CERT_WRAPPER_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// disable truncated debug symbols
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
|
||||
#include "yassl_types.hpp" // SignatureAlgorithm
|
||||
#include "buffer.hpp" // input_buffer
|
||||
#include "asn.hpp" // SignerList
|
||||
#include "openssl/ssl.h" // internal and external use
|
||||
#include STL_LIST_FILE
|
||||
#include STL_ALGORITHM_FILE
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
typedef unsigned char opaque;
|
||||
class X509; // forward openSSL type
|
||||
|
||||
using TaoCrypt::SignerList;
|
||||
|
||||
// an x509 version 3 certificate
|
||||
class x509 {
|
||||
uint length_;
|
||||
opaque* buffer_;
|
||||
public:
|
||||
explicit x509(uint sz);
|
||||
~x509();
|
||||
|
||||
uint get_length() const;
|
||||
const opaque* get_buffer() const;
|
||||
opaque* use_buffer();
|
||||
|
||||
x509(const x509&);
|
||||
x509& operator=(const x509&);
|
||||
private:
|
||||
void Swap(x509&);
|
||||
};
|
||||
|
||||
|
||||
// Certificate Manager keeps a list of the cert chain and public key
|
||||
class CertManager {
|
||||
typedef STL::list<x509*> CertList;
|
||||
|
||||
CertList list_; // self
|
||||
input_buffer privateKey_;
|
||||
|
||||
CertList peerList_; // peer
|
||||
input_buffer peerPublicKey_;
|
||||
X509* peerX509_; // peer's openSSL X509
|
||||
|
||||
SignatureAlgorithm keyType_; // self key type
|
||||
SignatureAlgorithm peerKeyType_; // peer's key type
|
||||
|
||||
SignerList signers_; // decoded CA keys and names
|
||||
// plus verified chained certs
|
||||
bool verifyPeer_;
|
||||
bool verifyNone_; // no error if verify fails
|
||||
bool failNoCert_;
|
||||
bool sendVerify_;
|
||||
VerifyCallback verifyCallback_; // user verify callback
|
||||
public:
|
||||
CertManager();
|
||||
~CertManager();
|
||||
|
||||
void AddPeerCert(x509* x); // take ownership
|
||||
void CopySelfCert(const x509* x);
|
||||
int CopyCaCert(const x509* x);
|
||||
int Validate();
|
||||
|
||||
int SetPrivateKey(const x509&);
|
||||
|
||||
const x509* get_cert() const;
|
||||
const opaque* get_peerKey() const;
|
||||
const opaque* get_privateKey() const;
|
||||
X509* get_peerX509() const;
|
||||
SignatureAlgorithm get_keyType() const;
|
||||
SignatureAlgorithm get_peerKeyType() const;
|
||||
|
||||
uint get_peerKeyLength() const;
|
||||
uint get_privateKeyLength() const;
|
||||
|
||||
bool verifyPeer() const;
|
||||
bool verifyNone() const;
|
||||
bool failNoCert() const;
|
||||
bool sendVerify() const;
|
||||
|
||||
void setVerifyPeer();
|
||||
void setVerifyNone();
|
||||
void setFailNoCert();
|
||||
void setSendVerify();
|
||||
void setPeerX509(X509*);
|
||||
void setVerifyCallback(VerifyCallback);
|
||||
private:
|
||||
CertManager(const CertManager&); // hide copy
|
||||
CertManager& operator=(const CertManager&); // and assign
|
||||
};
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_CERT_WRAPPER_HPP
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
|
||||
/* Headers we may want to use. */
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
/* #undef HAVE_ARPA_INET_H */
|
||||
/* #undef HAVE_CRYPT_H */
|
||||
/* #undef HAVE_DIRENT_H */
|
||||
/* #undef HAVE_EXECINFO_H */
|
||||
#define HAVE_FCNTL_H 1
|
||||
/* #undef HAVE_FENV_H */
|
||||
#define HAVE_FLOAT_H 1
|
||||
/* #undef HAVE_FPU_CONTROL_H */
|
||||
/* #undef HAVE_GRP_H */
|
||||
/* #undef HAVE_IEEEFP_H */
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_MALLOC_H 1
|
||||
#define HAVE_MEMORY_H 1
|
||||
/* #undef HAVE_NETINET_IN_H */
|
||||
/* #undef HAVE_PATHS_H */
|
||||
/* #undef HAVE_PWD_H */
|
||||
/* #undef HAVE_SCHED_H */
|
||||
/* #undef HAVE_SELECT_H */
|
||||
#define HAVE_STDDEF_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
#define HAVE_STRING_H 1
|
||||
/* #undef HAVE_SYNCH_H */
|
||||
/* #undef HAVE_SYSENT_H */
|
||||
/* #undef HAVE_SYS_FPU_H */
|
||||
/* #undef HAVE_SYS_IOCTL_H */
|
||||
/* #undef HAVE_SYS_IPC_H */
|
||||
/* #undef HAVE_SYS_MMAN_H */
|
||||
/* #undef HAVE_SYS_PRCTL_H */
|
||||
/* #undef HAVE_SYS_SELECT_H */
|
||||
/* #undef HAVE_SYS_SHM_H */
|
||||
/* #undef HAVE_SYS_SOCKET_H */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
/* #undef HAVE_SYS_STREAM_H */
|
||||
#define HAVE_SYS_TIMEB_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
/* #undef HAVE_SYS_UN_H */
|
||||
/* #undef HAVE_TERMIOS_H */
|
||||
/* #undef HAVE_TERMIO_H */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
/* #undef HAVE_UTIME_H */
|
||||
|
||||
/* Functions we may want to use. */
|
||||
#define HAVE_ACCESS 1
|
||||
/* #undef HAVE_AIOWAIT */
|
||||
/* #undef HAVE_ALARM */
|
||||
/* #undef HAVE_ALLOCA */
|
||||
/* #undef HAVE_BCMP */
|
||||
/* #undef HAVE_BFILL */
|
||||
/* #undef HAVE_BMOVE */
|
||||
/* #undef HAVE_BZERO */
|
||||
/* #undef HAVE_CLOCK_GETTIME */
|
||||
/* #undef HAVE_COMPRESS */
|
||||
/* #undef HAVE_CRYPT */
|
||||
/* #undef HAVE_DLERROR */
|
||||
/* #undef HAVE_DLOPEN */
|
||||
/* #undef HAVE_FCHMOD */
|
||||
/* #undef HAVE_FCNTL */
|
||||
/* #undef HAVE_FCONVERT */
|
||||
/* #undef HAVE_FDATASYNC */
|
||||
/* #undef HAVE_FESETROUND */
|
||||
/* #undef HAVE_FINITE */
|
||||
/* #undef HAVE_FP_EXCEPT */
|
||||
/* #undef HAVE_FSEEKO */
|
||||
/* #undef HAVE_FSYNC */
|
||||
/* #undef HAVE_GETADDRINFO */
|
||||
#define HAVE_GETCWD 1
|
||||
/* #undef HAVE_GETHOSTBYADDR_R */
|
||||
/* #undef HAVE_GETHOSTBYNAME_R */
|
||||
/* #undef HAVE_GETHRTIME */
|
||||
/* #undef HAVE_GETNAMEINFO */
|
||||
/* #undef HAVE_GETPAGESIZE */
|
||||
/* #undef HAVE_GETPASS */
|
||||
/* #undef HAVE_GETPASSPHRASE */
|
||||
/* #undef HAVE_GETPWNAM */
|
||||
/* #undef HAVE_GETPWUID */
|
||||
/* #undef HAVE_GETRLIMIT */
|
||||
/* #undef HAVE_GETRUSAGE */
|
||||
/* #undef HAVE_GETWD */
|
||||
/* #undef HAVE_GMTIME_R */
|
||||
/* #undef HAVE_INITGROUPS */
|
||||
/* #undef HAVE_ISNAN */
|
||||
#define HAVE_LDIV 1
|
||||
/* #undef HAVE_LOCALTIME_R */
|
||||
/* #undef HAVE_LOG2 */
|
||||
#define HAVE_LONGJMP 1
|
||||
/* #undef HAVE_LSTAT */
|
||||
/* #undef HAVE_MADVISE */
|
||||
/* #undef HAVE_DECL_MADVISE */
|
||||
/* #undef HAVE_MALLINFO */
|
||||
#define HAVE_MEMCPY 1
|
||||
#define HAVE_MEMCPY 1
|
||||
#define HAVE_MEMMOVE 1
|
||||
#define HAVE_MEMMOVE 1
|
||||
/* #undef HAVE_MKSTEMP */
|
||||
/* #undef HAVE_MLOCK */
|
||||
/* #undef HAVE_MLOCKALL */
|
||||
/* #undef HAVE_MMAP */
|
||||
/* #undef HAVE_MMAP64 */
|
||||
#define HAVE_PERROR 1
|
||||
/* #undef HAVE_POLL */
|
||||
/* #undef HAVE_PREAD */
|
||||
/* #undef HAVE_PTHREAD_ATTR_CREATE */
|
||||
/* #undef HAVE_PTHREAD_ATTR_GETSTACKSIZE */
|
||||
/* #undef HAVE_PTHREAD_ATTR_SETPRIO */
|
||||
/* #undef HAVE_PTHREAD_ATTR_SETSCHEDPARAM */
|
||||
/* #undef HAVE_PTHREAD_ATTR_SETSCOPE */
|
||||
/* #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE */
|
||||
/* #undef HAVE_PTHREAD_CONDATTR_CREATE */
|
||||
/* #undef HAVE_PTHREAD_INIT */
|
||||
/* #undef HAVE_PTHREAD_KEY_DELETE */
|
||||
/* #undef HAVE_PTHREAD_KEY_DELETE */
|
||||
/* #undef HAVE_PTHREAD_KILL */
|
||||
/* #undef HAVE_PTHREAD_RWLOCK_RDLOCK */
|
||||
/* #undef HAVE_PTHREAD_SETPRIO_NP */
|
||||
/* #undef HAVE_PTHREAD_SETSCHEDPARAM */
|
||||
/* #undef HAVE_PTHREAD_SIGMASK */
|
||||
/* #undef HAVE_PTHREAD_THREADMASK */
|
||||
/* #undef HAVE_PTHREAD_YIELD_NP */
|
||||
/* #undef HAVE_READDIR_R */
|
||||
/* #undef HAVE_READLINK */
|
||||
/* #undef HAVE_REALPATH */
|
||||
#define HAVE_RENAME 1
|
||||
/* #undef HAVE_RINT */
|
||||
/* #undef HAVE_SCHED_YIELD */
|
||||
/* #undef HAVE_SELECT */
|
||||
/* #undef HAVE_SETFD */
|
||||
/* #undef HAVE_SETFILEPOINTER */
|
||||
/* #undef HAVE_SIGACTION */
|
||||
/* #undef HAVE_SIGTHREADMASK */
|
||||
/* #undef HAVE_SIGWAIT */
|
||||
/* #undef HAVE_SLEEP */
|
||||
/* #undef HAVE_SNPRINTF */
|
||||
/* #undef HAVE_STPCPY */
|
||||
#define HAVE_STRERROR 1
|
||||
/* #undef HAVE_STRLCPY */
|
||||
#define HAVE_STRNLEN 1
|
||||
#define HAVE_STRPBRK 1
|
||||
/* #undef HAVE_STRSEP */
|
||||
#define HAVE_STRSTR 1
|
||||
/* #undef HAVE_STRTOK_R */
|
||||
/* #undef HAVE_STRTOK_R */
|
||||
#define HAVE_STRTOL 1
|
||||
/* #undef HAVE_STRTOLL */
|
||||
#define HAVE_STRTOUL 1
|
||||
/* #undef HAVE_STRTOULL */
|
||||
#define HAVE_TELL 1
|
||||
/* #undef HAVE_THR_SETCONCURRENCY */
|
||||
/* #undef HAVE_THR_YIELD */
|
||||
/* #undef HAVE_VASPRINTF */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Symbols we may use */
|
||||
/* #undef HAVE_SYS_ERRLIST */
|
||||
/* used by stacktrace functions */
|
||||
/* #undef HAVE_BSS_START */
|
||||
|
||||
/* Does "struct timespec" have a "sec" and "nsec" field? */
|
||||
/* #undef HAVE_TIMESPEC_TS_SEC */
|
||||
|
||||
/* Types we may use */
|
||||
#define SIZEOF_CHAR 1
|
||||
#if SIZEOF_CHAR
|
||||
# define HAVE_CHAR 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_CHARP 4
|
||||
#if SIZEOF_CHARP
|
||||
# define HAVE_CHARP 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_SHORT 2
|
||||
#if SIZEOF_SHORT
|
||||
# define HAVE_SHORT 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#if SIZEOF_INT
|
||||
# define HAVE_INT 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_LONG 4
|
||||
#if SIZEOF_LONG
|
||||
# define HAVE_LONG 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
#if SIZEOF_LONG_LONG
|
||||
# define HAVE_LONG_LONG 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_OFF_T 4
|
||||
#if SIZEOF_OFF_T
|
||||
# define HAVE_OFF_T 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_SIGSET_T */
|
||||
#if SIZEOF_SIGSET_T
|
||||
# define HAVE_SIGSET_T 1
|
||||
#endif
|
||||
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#if SIZEOF_SIZE_T
|
||||
# define HAVE_SIZE_T 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_UCHAR */
|
||||
#if SIZEOF_UCHAR
|
||||
# define HAVE_UCHAR 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_UINT */
|
||||
#if SIZEOF_UINT
|
||||
# define HAVE_UINT 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_ULONG */
|
||||
#if SIZEOF_ULONG
|
||||
# define HAVE_ULONG 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT8 */
|
||||
#if SIZEOF_INT8
|
||||
# define HAVE_INT8 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT8 */
|
||||
#if SIZEOF_UINT8
|
||||
# define HAVE_UINT8 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT16 */
|
||||
#if SIZEOF_INT16
|
||||
# define HAVE_INT16 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT16 */
|
||||
#if SIZEOF_UINT16
|
||||
# define HAVE_UINT16 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT32 */
|
||||
#if SIZEOF_INT32
|
||||
# define HAVE_INT32 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT32 */
|
||||
#if SIZEOF_UINT32
|
||||
# define HAVE_UINT32 1
|
||||
#endif
|
||||
/* #undef SIZEOF_U_INT32_T */
|
||||
#if SIZEOF_U_INT32_T
|
||||
# define HAVE_U_INT32_T 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_INT64 */
|
||||
#if SIZEOF_INT64
|
||||
# define HAVE_INT64 1
|
||||
#endif
|
||||
/* #undef SIZEOF_UINT64 */
|
||||
#if SIZEOF_UINT64
|
||||
# define HAVE_UINT64 1
|
||||
#endif
|
||||
|
||||
/* #undef SIZEOF_SOCKLEN_T */
|
||||
#if SIZEOF_SOCKLEN_T
|
||||
# define HAVE_SOCKLEN_T 1
|
||||
#endif
|
||||
|
||||
/* XXX mysql_client_test uses this -- rip it out, please! */
|
||||
#define MAX_INDEXES 64
|
||||
|
||||
#define QSORT_TYPE_IS_VOID 1
|
||||
#define RETQSORTTYPE void
|
||||
|
||||
#define SIGNAL_RETURN_TYPE_IS_VOID 1
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler calls
|
||||
it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
# define inline
|
||||
#endif
|
||||
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
#define STACK_DIRECTION -1
|
||||
|
||||
#define SHAREDIR "share"
|
||||
#define THREAD 1
|
||||
#define THREAD_SAFE_CLIENT 1
|
||||
|
||||
#define DEFAULT_CHARSET_HOME "C:/mysql/"
|
||||
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* The crypto wrapper header is used to define policies for the cipher
|
||||
* components used by SSL. There are 3 policies to consider:
|
||||
*
|
||||
* 1) MAC, the Message Authentication Code used for each Message
|
||||
* 2) Bulk Cipher, the Cipher used to encrypt/decrypt each Message
|
||||
* 3) Atuhentication, the Digitial Signing/Verifiaction scheme used
|
||||
*
|
||||
* This header doesn't rely on a specific crypto libraries internals,
|
||||
* only the implementation should.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_CRYPTO_WRAPPER_HPP
|
||||
#define yaSSL_CRYPTO_WRAPPER_HPP
|
||||
|
||||
#include "yassl_types.hpp"
|
||||
#include <stdio.h> // FILE
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
// Digest policy should implement a get_digest, update, and get sizes for pad
|
||||
// and digest
|
||||
struct Digest : public virtual_base {
|
||||
virtual void get_digest(byte*) = 0;
|
||||
virtual void get_digest(byte*, const byte*, unsigned int) = 0;
|
||||
virtual void update(const byte*, unsigned int) = 0;
|
||||
virtual uint get_digestSize() const = 0;
|
||||
virtual uint get_padSize() const = 0;
|
||||
virtual ~Digest() {}
|
||||
};
|
||||
|
||||
|
||||
// For use with NULL Digests
|
||||
struct NO_MAC : public Digest {
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
};
|
||||
|
||||
|
||||
// MD5 Digest
|
||||
class MD5 : public Digest {
|
||||
public:
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
MD5();
|
||||
~MD5();
|
||||
MD5(const MD5&);
|
||||
MD5& operator=(const MD5&);
|
||||
private:
|
||||
struct MD5Impl;
|
||||
MD5Impl* pimpl_;
|
||||
};
|
||||
|
||||
|
||||
// SHA-1 Digest
|
||||
class SHA : public Digest {
|
||||
public:
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
SHA();
|
||||
~SHA();
|
||||
SHA(const SHA&);
|
||||
SHA& operator=(const SHA&);
|
||||
private:
|
||||
struct SHAImpl;
|
||||
SHAImpl* pimpl_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// RIPEMD-160 Digest
|
||||
class RMD : public Digest {
|
||||
public:
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
RMD();
|
||||
~RMD();
|
||||
RMD(const RMD&);
|
||||
RMD& operator=(const RMD&);
|
||||
private:
|
||||
struct RMDImpl;
|
||||
RMDImpl* pimpl_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// HMAC_MD5
|
||||
class HMAC_MD5 : public Digest {
|
||||
public:
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
HMAC_MD5(const byte*, unsigned int);
|
||||
~HMAC_MD5();
|
||||
private:
|
||||
struct HMAC_MD5Impl;
|
||||
HMAC_MD5Impl* pimpl_;
|
||||
|
||||
HMAC_MD5(const HMAC_MD5&);
|
||||
HMAC_MD5& operator=(const HMAC_MD5&);
|
||||
};
|
||||
|
||||
|
||||
// HMAC_SHA-1
|
||||
class HMAC_SHA : public Digest {
|
||||
public:
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
HMAC_SHA(const byte*, unsigned int);
|
||||
~HMAC_SHA();
|
||||
private:
|
||||
struct HMAC_SHAImpl;
|
||||
HMAC_SHAImpl* pimpl_;
|
||||
|
||||
HMAC_SHA(const HMAC_SHA&);
|
||||
HMAC_SHA& operator=(const HMAC_SHA&);
|
||||
};
|
||||
|
||||
|
||||
// HMAC_RMD
|
||||
class HMAC_RMD : public Digest {
|
||||
public:
|
||||
void get_digest(byte*);
|
||||
void get_digest(byte*, const byte*, unsigned int);
|
||||
void update(const byte*, unsigned int);
|
||||
uint get_digestSize() const;
|
||||
uint get_padSize() const;
|
||||
HMAC_RMD(const byte*, unsigned int);
|
||||
~HMAC_RMD();
|
||||
private:
|
||||
struct HMAC_RMDImpl;
|
||||
HMAC_RMDImpl* pimpl_;
|
||||
|
||||
HMAC_RMD(const HMAC_RMD&);
|
||||
HMAC_RMD& operator=(const HMAC_RMD&);
|
||||
};
|
||||
|
||||
|
||||
// BulkCipher policy should implement encrypt, decrypt, get block size,
|
||||
// and set keys for encrypt and decrypt
|
||||
struct BulkCipher : public virtual_base {
|
||||
virtual void encrypt(byte*, const byte*, unsigned int) = 0;
|
||||
virtual void decrypt(byte*, const byte*, unsigned int) = 0;
|
||||
virtual void set_encryptKey(const byte*, const byte* = 0) = 0;
|
||||
virtual void set_decryptKey(const byte*, const byte* = 0) = 0;
|
||||
virtual uint get_blockSize() const = 0;
|
||||
virtual int get_keySize() const = 0;
|
||||
virtual int get_ivSize() const = 0;
|
||||
virtual ~BulkCipher() {}
|
||||
};
|
||||
|
||||
|
||||
// For use with NULL Ciphers
|
||||
struct NO_Cipher : public BulkCipher {
|
||||
void encrypt(byte*, const byte*, unsigned int) {}
|
||||
void decrypt(byte*, const byte*, unsigned int) {}
|
||||
void set_encryptKey(const byte*, const byte*) {}
|
||||
void set_decryptKey(const byte*, const byte*) {}
|
||||
uint get_blockSize() const { return 0; }
|
||||
int get_keySize() const { return 0; }
|
||||
int get_ivSize() const { return 0; }
|
||||
};
|
||||
|
||||
|
||||
// SSLv3 and TLSv1 always use DES in CBC mode so IV is required
|
||||
class DES : public BulkCipher {
|
||||
public:
|
||||
void encrypt(byte*, const byte*, unsigned int);
|
||||
void decrypt(byte*, const byte*, unsigned int);
|
||||
void set_encryptKey(const byte*, const byte*);
|
||||
void set_decryptKey(const byte*, const byte*);
|
||||
uint get_blockSize() const { return DES_BLOCK; }
|
||||
int get_keySize() const { return DES_KEY_SZ; }
|
||||
int get_ivSize() const { return DES_IV_SZ; }
|
||||
DES();
|
||||
~DES();
|
||||
private:
|
||||
struct DESImpl;
|
||||
DESImpl* pimpl_;
|
||||
|
||||
DES(const DES&); // hide copy
|
||||
DES& operator=(const DES&); // & assign
|
||||
};
|
||||
|
||||
|
||||
// 3DES Encrypt-Decrypt-Encrypt in CBC mode
|
||||
class DES_EDE : public BulkCipher {
|
||||
public:
|
||||
void encrypt(byte*, const byte*, unsigned int);
|
||||
void decrypt(byte*, const byte*, unsigned int);
|
||||
void set_encryptKey(const byte*, const byte*);
|
||||
void set_decryptKey(const byte*, const byte*);
|
||||
uint get_blockSize() const { return DES_BLOCK; }
|
||||
int get_keySize() const { return DES_EDE_KEY_SZ; }
|
||||
int get_ivSize() const { return DES_IV_SZ; }
|
||||
DES_EDE();
|
||||
~DES_EDE();
|
||||
private:
|
||||
struct DES_EDEImpl;
|
||||
DES_EDEImpl* pimpl_;
|
||||
|
||||
DES_EDE(const DES_EDE&); // hide copy
|
||||
DES_EDE& operator=(const DES_EDE&); // & assign
|
||||
};
|
||||
|
||||
|
||||
// Alledged RC4
|
||||
class RC4 : public BulkCipher {
|
||||
public:
|
||||
void encrypt(byte*, const byte*, unsigned int);
|
||||
void decrypt(byte*, const byte*, unsigned int);
|
||||
void set_encryptKey(const byte*, const byte*);
|
||||
void set_decryptKey(const byte*, const byte*);
|
||||
uint get_blockSize() const { return 0; }
|
||||
int get_keySize() const { return RC4_KEY_SZ; }
|
||||
int get_ivSize() const { return 0; }
|
||||
RC4();
|
||||
~RC4();
|
||||
private:
|
||||
struct RC4Impl;
|
||||
RC4Impl* pimpl_;
|
||||
|
||||
RC4(const RC4&); // hide copy
|
||||
RC4& operator=(const RC4&); // & assign
|
||||
};
|
||||
|
||||
|
||||
// AES
|
||||
class AES : public BulkCipher {
|
||||
public:
|
||||
void encrypt(byte*, const byte*, unsigned int);
|
||||
void decrypt(byte*, const byte*, unsigned int);
|
||||
void set_encryptKey(const byte*, const byte*);
|
||||
void set_decryptKey(const byte*, const byte*);
|
||||
uint get_blockSize() const { return AES_BLOCK_SZ; }
|
||||
int get_keySize() const;
|
||||
int get_ivSize() const { return AES_IV_SZ; }
|
||||
explicit AES(unsigned int = AES_128_KEY_SZ);
|
||||
~AES();
|
||||
private:
|
||||
struct AESImpl;
|
||||
AESImpl* pimpl_;
|
||||
|
||||
AES(const AES&); // hide copy
|
||||
AES& operator=(const AES&); // & assign
|
||||
};
|
||||
|
||||
|
||||
// Random number generator
|
||||
class RandomPool {
|
||||
public:
|
||||
void Fill(opaque* dst, uint sz) const;
|
||||
RandomPool();
|
||||
~RandomPool();
|
||||
|
||||
int GetError() const;
|
||||
|
||||
friend class RSA;
|
||||
friend class DSS;
|
||||
friend class DiffieHellman;
|
||||
private:
|
||||
struct RandomImpl;
|
||||
RandomImpl* pimpl_;
|
||||
|
||||
RandomPool(const RandomPool&); // hide copy
|
||||
RandomPool& operator=(const RandomPool&); // & assign
|
||||
};
|
||||
|
||||
|
||||
// Authentication policy should implement sign, and verify
|
||||
struct Auth : public virtual_base {
|
||||
virtual void sign(byte*, const byte*, unsigned int, const RandomPool&) = 0;
|
||||
virtual bool verify(const byte*, unsigned int, const byte*,
|
||||
unsigned int) = 0;
|
||||
virtual uint get_signatureLength() const = 0;
|
||||
virtual ~Auth() {}
|
||||
};
|
||||
|
||||
|
||||
// For use with NULL Authentication schemes
|
||||
struct NO_Auth : public Auth {
|
||||
void sign(byte*, const byte*, unsigned int, const RandomPool&) {}
|
||||
bool verify(const byte*, unsigned int, const byte*, unsigned int)
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
|
||||
// Digitial Signature Standard scheme
|
||||
class DSS : public Auth {
|
||||
public:
|
||||
void sign(byte*, const byte*, unsigned int, const RandomPool&);
|
||||
bool verify(const byte*, unsigned int, const byte*, unsigned int);
|
||||
uint get_signatureLength() const;
|
||||
DSS(const byte*, unsigned int, bool publicKey = true);
|
||||
~DSS();
|
||||
private:
|
||||
struct DSSImpl;
|
||||
DSSImpl* pimpl_;
|
||||
|
||||
DSS(const DSS&);
|
||||
DSS& operator=(const DSS&);
|
||||
};
|
||||
|
||||
|
||||
// RSA Authentication and exchange
|
||||
class RSA : public Auth {
|
||||
public:
|
||||
void sign(byte*, const byte*, unsigned int, const RandomPool&);
|
||||
bool verify(const byte*, unsigned int, const byte*, unsigned int);
|
||||
void encrypt(byte*, const byte*, unsigned int, const RandomPool&);
|
||||
void decrypt(byte*, const byte*, unsigned int, const RandomPool&);
|
||||
uint get_signatureLength() const;
|
||||
uint get_cipherLength() const;
|
||||
RSA(const byte*, unsigned int, bool publicKey = true);
|
||||
~RSA();
|
||||
private:
|
||||
struct RSAImpl;
|
||||
RSAImpl* pimpl_;
|
||||
|
||||
RSA(const RSA&); // hide copy
|
||||
RSA& operator=(const RSA&); // & assing
|
||||
};
|
||||
|
||||
|
||||
class Integer;
|
||||
|
||||
// Diffie-Hellman agreement
|
||||
// hide for now TODO: figure out a way to give access to C clients p and g args
|
||||
class DiffieHellman {
|
||||
public:
|
||||
DiffieHellman(const byte*, unsigned int, const byte*, unsigned int,
|
||||
const byte*, unsigned int, const RandomPool& random);
|
||||
//DiffieHellman(const char*, const RandomPool&);
|
||||
DiffieHellman(const Integer&, const Integer&, const RandomPool&);
|
||||
~DiffieHellman();
|
||||
|
||||
DiffieHellman(const DiffieHellman&);
|
||||
DiffieHellman& operator=(const DiffieHellman&);
|
||||
|
||||
uint get_agreedKeyLength() const;
|
||||
const byte* get_agreedKey() const;
|
||||
const byte* get_publicKey() const;
|
||||
void makeAgreement(const byte*, unsigned int);
|
||||
|
||||
void set_sizes(int&, int&, int&) const;
|
||||
void get_parms(byte*, byte*, byte*) const;
|
||||
private:
|
||||
struct DHImpl;
|
||||
DHImpl* pimpl_;
|
||||
};
|
||||
|
||||
|
||||
// Lagrge Integer
|
||||
class Integer {
|
||||
public:
|
||||
Integer();
|
||||
~Integer();
|
||||
|
||||
Integer(const Integer&);
|
||||
Integer& operator=(const Integer&);
|
||||
|
||||
void assign(const byte*, unsigned int);
|
||||
|
||||
friend class DiffieHellman;
|
||||
private:
|
||||
struct IntegerImpl;
|
||||
IntegerImpl* pimpl_;
|
||||
};
|
||||
|
||||
|
||||
class x509;
|
||||
|
||||
|
||||
struct EncryptedInfo {
|
||||
enum { IV_SZ = 32, NAME_SZ = 80 };
|
||||
char name[NAME_SZ]; // max one line
|
||||
byte iv[IV_SZ]; // in base16 rep
|
||||
uint ivSz;
|
||||
bool set;
|
||||
|
||||
EncryptedInfo() : ivSz(0), set(false) {}
|
||||
};
|
||||
|
||||
x509* PemToDer(FILE*, CertType, EncryptedInfo* info = 0);
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_CRYPTO_WRAPPER_HPP
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* The factory header defines an Object Factory, used by SSL message and
|
||||
* handshake types.
|
||||
*
|
||||
* See Desgin Pattern in GoF and Alexandrescu's chapter in Modern C++ Design,
|
||||
* page 208
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef yaSSL_FACTORY_HPP
|
||||
#define yaSSL_FACTORY_HPP
|
||||
|
||||
#include STL_VECTOR_FILE
|
||||
#include STL_PAIR_FILE
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
// Factory uses its callback map to create objects by id,
|
||||
// returning an abstract base pointer
|
||||
template<class AbstractProduct,
|
||||
typename IdentifierType = int,
|
||||
typename ProductCreator = AbstractProduct* (*)()
|
||||
>
|
||||
class Factory {
|
||||
typedef STL::pair<IdentifierType, ProductCreator> CallBack;
|
||||
typedef STL::vector<CallBack> CallBackVector;
|
||||
|
||||
CallBackVector callbacks_;
|
||||
public:
|
||||
// pass function pointer to register all callbacks upon creation
|
||||
explicit Factory(void (*init)(Factory<AbstractProduct, IdentifierType,
|
||||
ProductCreator>&))
|
||||
{
|
||||
init(*this);
|
||||
}
|
||||
|
||||
// reserve place in vector before registering, used by init funcion
|
||||
void Reserve(size_t sz)
|
||||
{
|
||||
callbacks_.reserve(sz);
|
||||
}
|
||||
|
||||
// register callback
|
||||
void Register(const IdentifierType& id, ProductCreator pc)
|
||||
{
|
||||
callbacks_.push_back(STL::make_pair(id, pc));
|
||||
}
|
||||
|
||||
// THE Creator, returns a new object of the proper type or 0
|
||||
AbstractProduct* CreateObject(const IdentifierType& id) const
|
||||
{
|
||||
typedef typename STL::vector<CallBack>::const_iterator cIter;
|
||||
|
||||
cIter first = callbacks_.begin();
|
||||
cIter last = callbacks_.end();
|
||||
|
||||
while (first != last) {
|
||||
if (first->first == id)
|
||||
break;
|
||||
++first;
|
||||
}
|
||||
|
||||
if (first == callbacks_.end())
|
||||
return 0;
|
||||
return (first->second)();
|
||||
}
|
||||
private:
|
||||
Factory(const Factory&); // hide copy
|
||||
Factory& operator=(const Factory&); // and assign
|
||||
};
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_FACTORY_HPP
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* The handshake header declares function prototypes for creating and reading
|
||||
* the various handshake messages.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef yaSSL_HANDSHAKE_HPP
|
||||
#define yaSSL_HANDSHAKE_HPP
|
||||
|
||||
#include "yassl_types.hpp"
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
// forward decls
|
||||
class SSL;
|
||||
class Finished;
|
||||
class Data;
|
||||
class Alert;
|
||||
struct Hashes;
|
||||
|
||||
enum BufferOutput { buffered, unbuffered };
|
||||
|
||||
void sendClientHello(SSL&);
|
||||
void sendServerHello(SSL&, BufferOutput = buffered);
|
||||
void sendServerHelloDone(SSL&, BufferOutput = buffered);
|
||||
void sendClientKeyExchange(SSL&, BufferOutput = buffered);
|
||||
void sendServerKeyExchange(SSL&, BufferOutput = buffered);
|
||||
void sendChangeCipher(SSL&, BufferOutput = buffered);
|
||||
void sendFinished(SSL&, ConnectionEnd, BufferOutput = buffered);
|
||||
void sendCertificate(SSL&, BufferOutput = buffered);
|
||||
void sendCertificateRequest(SSL&, BufferOutput = buffered);
|
||||
void sendCertificateVerify(SSL&, BufferOutput = buffered);
|
||||
int sendData(SSL&, const void*, int);
|
||||
int sendAlert(SSL& ssl, const Alert& alert);
|
||||
|
||||
int receiveData(SSL&, Data&, bool peek = false);
|
||||
void processReply(SSL&);
|
||||
|
||||
void buildFinished(SSL&, Finished&, const opaque*);
|
||||
void build_certHashes(SSL&, Hashes&);
|
||||
|
||||
void hmac(SSL&, byte*, const byte*, uint, ContentType, bool verify = false);
|
||||
void TLS_hmac(SSL&, byte*, const byte*, uint, ContentType,
|
||||
bool verify = false);
|
||||
void PRF(byte* digest, uint digLen, const byte* secret, uint secLen,
|
||||
const byte* label, uint labLen, const byte* seed, uint seedLen);
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_HANDSHAKE_HPP
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* lock.hpp provides an os specific Lock, locks mutex on entry and unlocks
|
||||
* automatically upon exit, no-ops provided for Single Threaded
|
||||
*/
|
||||
|
||||
#ifndef yaSSL_LOCK_HPP
|
||||
#define yaSSL_LOCK_HPP
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
#ifdef MULTI_THREADED
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
class Mutex {
|
||||
CRITICAL_SECTION cs_;
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
class Lock;
|
||||
friend class Lock;
|
||||
|
||||
class Lock {
|
||||
Mutex& mutex_;
|
||||
public:
|
||||
explicit Lock(Mutex& lm);
|
||||
~Lock();
|
||||
};
|
||||
};
|
||||
#else // _WIN32
|
||||
#include <pthread.h>
|
||||
|
||||
class Mutex {
|
||||
pthread_mutex_t mutex_;
|
||||
public:
|
||||
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
class Lock;
|
||||
friend class Lock;
|
||||
|
||||
class Lock {
|
||||
Mutex& mutex_;
|
||||
public:
|
||||
explicit Lock(Mutex& lm);
|
||||
~Lock();
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _WIN32
|
||||
#else // MULTI_THREADED (WE'RE SINGLE)
|
||||
|
||||
class Mutex {
|
||||
public:
|
||||
class Lock {
|
||||
public:
|
||||
explicit Lock(Mutex&) {}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // MULTI_THREADED
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
#endif // yaSSL_LOCK_HPP
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL log interface
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef yaSSL_LOG_HPP
|
||||
#define yaSSL_LOG_HPP
|
||||
|
||||
#include "socket_wrapper.hpp"
|
||||
|
||||
#ifdef YASSL_LOG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
|
||||
// Debug logger
|
||||
class Log {
|
||||
#ifdef YASSL_LOG
|
||||
FILE* log_;
|
||||
#endif
|
||||
public:
|
||||
explicit Log(const char* str = "yaSSL.log");
|
||||
~Log();
|
||||
|
||||
void Trace(const char*);
|
||||
void ShowTCP(socket_t, bool ended = false);
|
||||
void ShowData(uint, bool sent = false);
|
||||
};
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_LOG_HPP
|
||||
@@ -0,0 +1,18 @@
|
||||
/* crypto.h for openSSL */
|
||||
|
||||
#ifndef ysSSL_crypto_h__
|
||||
#define yaSSL_crypto_h__
|
||||
|
||||
#ifdef YASSL_PREFIX
|
||||
#include "prefix_crypto.h"
|
||||
#endif
|
||||
|
||||
const char* SSLeay_version(int type);
|
||||
|
||||
#define SSLEAY_NUMBER_DEFINED
|
||||
#define SSLEAY_VERSION 0x0900L
|
||||
#define SSLEAY_VERSION_NUMBER SSLEAY_VERSION
|
||||
|
||||
|
||||
#endif /* yaSSL_crypto_h__ */
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* des.h for openssl */
|
||||
@@ -0,0 +1 @@
|
||||
/* des_old.h for openvn */
|
||||
@@ -0,0 +1,5 @@
|
||||
/* engine.h for libcurl */
|
||||
|
||||
#undef HAVE_OPENSSL_ENGINE_H
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/* err.h for openssl */
|
||||
|
||||
#ifndef yaSSL_err_h__
|
||||
#define yaSSL_err_h__
|
||||
|
||||
|
||||
|
||||
#endif /* yaSSL_err_h__ */
|
||||
@@ -0,0 +1,10 @@
|
||||
/* evp.h for openSSL */
|
||||
|
||||
#ifndef SSLEAY_NUMBER_DEFINED
|
||||
#define SSLEAY_NUMBER_DEFINED
|
||||
|
||||
/* for OpenVPN */
|
||||
#define SSLEAY_VERSION_NUMBER 0x0090700f
|
||||
|
||||
|
||||
#endif /* SSLEAY_NUMBER_DEFINED */
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# This script generates defines for all functions
|
||||
# in yassl/include/openssl/ so they are renamed to
|
||||
# ya<old_function_name>. Hopefully that is unique enough.
|
||||
#
|
||||
# The script is to be run manually when we import
|
||||
# a new version of yaSSL
|
||||
#
|
||||
|
||||
|
||||
|
||||
# Find all functions in "input" and add macros
|
||||
# to prefix/rename them into "output
|
||||
sub generate_prefix($$)
|
||||
{
|
||||
my $input= shift;
|
||||
my $output= shift;
|
||||
open(IN, $input)
|
||||
or die("Can't open input file $input: $!");
|
||||
open(OUT, ">", $output)
|
||||
or mtr_error("Can't open output file $output: $!");
|
||||
|
||||
while (<IN>)
|
||||
{
|
||||
chomp;
|
||||
|
||||
if ( /typedef/ )
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
if ( /^\s*[a-zA-Z0-9*_ ]+\s+\*?([_a-zA-Z0-9]+)\s*\(/ )
|
||||
{
|
||||
print OUT "#define $1 ya$1\n";
|
||||
}
|
||||
}
|
||||
|
||||
close OUT;
|
||||
close IN;
|
||||
}
|
||||
|
||||
generate_prefix("ssl.h", "prefix_ssl.h");
|
||||
generate_prefix("crypto.h", "prefix_crypto.h");
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* hmac.h for openvpn */
|
||||
@@ -0,0 +1,2 @@
|
||||
/* lhash.h for openSSL */
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* md4.h for libcurl */
|
||||
@@ -0,0 +1,4 @@
|
||||
/* md5.h for openssl */
|
||||
|
||||
#include "ssl.h" /* in there for now */
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* objects.h for openvpn */
|
||||
@@ -0,0 +1,12 @@
|
||||
/* opensslv.h compatibility */
|
||||
|
||||
#ifndef yaSSL_opensslv_h__
|
||||
#define yaSSL_opensslv_h__
|
||||
|
||||
|
||||
/* api version compatibility */
|
||||
#define OPENSSL_VERSION_NUMBER 0x0090700f
|
||||
|
||||
|
||||
#endif /* yaSSLopensslv_h__ */
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* pem.h for libcurl */
|
||||
@@ -0,0 +1,5 @@
|
||||
/* pkcs12.h for libcurl */
|
||||
|
||||
|
||||
#undef HAVE_OPENSSL_PKCS12_H
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#define SSLeay_version yaSSLeay_version
|
||||
@@ -0,0 +1,169 @@
|
||||
#define Copyright yaCopyright
|
||||
#define yaSSL_CleanUp yayaSSL_CleanUp
|
||||
#define BN_bin2bn yaBN_bin2bn
|
||||
#define DH_new yaDH_new
|
||||
#define DH_free yaDH_free
|
||||
#define RSA_free yaRSA_free
|
||||
#define RSA_generate_key yaRSA_generate_key
|
||||
#define X509_free yaX509_free
|
||||
#define X509_STORE_CTX_get_current_cert yaX509_STORE_CTX_get_current_cert
|
||||
#define X509_STORE_CTX_get_error yaX509_STORE_CTX_get_error
|
||||
#define X509_STORE_CTX_get_error_depth yaX509_STORE_CTX_get_error_depth
|
||||
#define X509_NAME_oneline yaX509_NAME_oneline
|
||||
#define X509_get_issuer_name yaX509_get_issuer_name
|
||||
#define X509_get_subject_name yaX509_get_subject_name
|
||||
#define X509_verify_cert_error_string yaX509_verify_cert_error_string
|
||||
#define X509_LOOKUP_add_dir yaX509_LOOKUP_add_dir
|
||||
#define X509_LOOKUP_load_file yaX509_LOOKUP_load_file
|
||||
#define X509_LOOKUP_hash_dir yaX509_LOOKUP_hash_dir
|
||||
#define X509_LOOKUP_file yaX509_LOOKUP_file
|
||||
#define X509_STORE_add_lookup yaX509_STORE_add_lookup
|
||||
#define X509_STORE_new yaX509_STORE_new
|
||||
#define X509_STORE_get_by_subject yaX509_STORE_get_by_subject
|
||||
#define ERR_get_error_line_data yaERR_get_error_line_data
|
||||
#define ERR_print_errors_fp yaERR_print_errors_fp
|
||||
#define ERR_error_string yaERR_error_string
|
||||
#define ERR_remove_state yaERR_remove_state
|
||||
#define ERR_get_error yaERR_get_error
|
||||
#define ERR_peek_error yaERR_peek_error
|
||||
#define ERR_GET_REASON yaERR_GET_REASON
|
||||
#define SSL_CTX_new yaSSL_CTX_new
|
||||
#define SSL_new yaSSL_new
|
||||
#define SSL_set_fd yaSSL_set_fd
|
||||
#define SSL_get_fd yaSSL_get_fd
|
||||
#define SSL_connect yaSSL_connect
|
||||
#define SSL_write yaSSL_write
|
||||
#define SSL_read yaSSL_read
|
||||
#define SSL_accept yaSSL_accept
|
||||
#define SSL_CTX_free yaSSL_CTX_free
|
||||
#define SSL_free yaSSL_free
|
||||
#define SSL_clear yaSSL_clear
|
||||
#define SSL_shutdown yaSSL_shutdown
|
||||
#define SSL_set_connect_state yaSSL_set_connect_state
|
||||
#define SSL_set_accept_state yaSSL_set_accept_state
|
||||
#define SSL_do_handshake yaSSL_do_handshake
|
||||
#define SSL_get_cipher yaSSL_get_cipher
|
||||
#define SSL_get_cipher_name yaSSL_get_cipher_name
|
||||
#define SSL_get_shared_ciphers yaSSL_get_shared_ciphers
|
||||
#define SSL_get_cipher_list yaSSL_get_cipher_list
|
||||
#define SSL_get_version yaSSL_get_version
|
||||
#define SSLeay_version yaSSLeay_version
|
||||
#define SSL_get_error yaSSL_get_error
|
||||
#define SSL_load_error_strings yaSSL_load_error_strings
|
||||
#define SSL_set_session yaSSL_set_session
|
||||
#define SSL_get_session yaSSL_get_session
|
||||
#define SSL_flush_sessions yaSSL_flush_sessions
|
||||
#define SSL_SESSION_set_timeout yaSSL_SESSION_set_timeout
|
||||
#define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode
|
||||
#define SSL_get_peer_certificate yaSSL_get_peer_certificate
|
||||
#define SSL_get_verify_result yaSSL_get_verify_result
|
||||
#define SSL_CTX_set_verify yaSSL_CTX_set_verify
|
||||
#define SSL_CTX_load_verify_locations yaSSL_CTX_load_verify_locations
|
||||
#define SSL_CTX_set_default_verify_paths yaSSL_CTX_set_default_verify_paths
|
||||
#define SSL_CTX_check_private_key yaSSL_CTX_check_private_key
|
||||
#define SSL_CTX_set_session_id_context yaSSL_CTX_set_session_id_context
|
||||
#define SSL_CTX_set_tmp_rsa_callback yaSSL_CTX_set_tmp_rsa_callback
|
||||
#define SSL_CTX_set_options yaSSL_CTX_set_options
|
||||
#define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode
|
||||
#define SSL_CTX_set_timeout yaSSL_CTX_set_timeout
|
||||
#define SSL_CTX_use_certificate_chain_file yaSSL_CTX_use_certificate_chain_file
|
||||
#define SSL_CTX_set_default_passwd_cb yaSSL_CTX_set_default_passwd_cb
|
||||
#define SSL_CTX_use_RSAPrivateKey_file yaSSL_CTX_use_RSAPrivateKey_file
|
||||
#define SSL_CTX_set_info_callback yaSSL_CTX_set_info_callback
|
||||
#define SSL_CTX_sess_accept yaSSL_CTX_sess_accept
|
||||
#define SSL_CTX_sess_connect yaSSL_CTX_sess_connect
|
||||
#define SSL_CTX_sess_accept_good yaSSL_CTX_sess_accept_good
|
||||
#define SSL_CTX_sess_connect_good yaSSL_CTX_sess_connect_good
|
||||
#define SSL_CTX_sess_accept_renegotiate yaSSL_CTX_sess_accept_renegotiate
|
||||
#define SSL_CTX_sess_connect_renegotiate yaSSL_CTX_sess_connect_renegotiate
|
||||
#define SSL_CTX_sess_hits yaSSL_CTX_sess_hits
|
||||
#define SSL_CTX_sess_cb_hits yaSSL_CTX_sess_cb_hits
|
||||
#define SSL_CTX_sess_cache_full yaSSL_CTX_sess_cache_full
|
||||
#define SSL_CTX_sess_misses yaSSL_CTX_sess_misses
|
||||
#define SSL_CTX_sess_timeouts yaSSL_CTX_sess_timeouts
|
||||
#define SSL_CTX_sess_number yaSSL_CTX_sess_number
|
||||
#define SSL_CTX_sess_get_cache_size yaSSL_CTX_sess_get_cache_size
|
||||
#define SSL_CTX_get_verify_mode yaSSL_CTX_get_verify_mode
|
||||
#define SSL_get_verify_mode yaSSL_get_verify_mode
|
||||
#define SSL_CTX_get_verify_depth yaSSL_CTX_get_verify_depth
|
||||
#define SSL_get_verify_depth yaSSL_get_verify_depth
|
||||
#define SSL_get_default_timeout yaSSL_get_default_timeout
|
||||
#define SSL_CTX_get_session_cache_mode yaSSL_CTX_get_session_cache_mode
|
||||
#define SSL_session_reused yaSSL_session_reused
|
||||
#define SSL_set_rfd yaSSL_set_rfd
|
||||
#define SSL_set_wfd yaSSL_set_wfd
|
||||
#define SSL_set_shutdown yaSSL_set_shutdown
|
||||
#define SSL_set_quiet_shutdown yaSSL_set_quiet_shutdown
|
||||
#define SSL_get_quiet_shutdown yaSSL_get_quiet_shutdown
|
||||
#define SSL_want_read yaSSL_want_read
|
||||
#define SSL_want_write yaSSL_want_write
|
||||
#define SSL_pending yaSSL_pending
|
||||
#define SSLv3_method yaSSLv3_method
|
||||
#define SSLv3_server_method yaSSLv3_server_method
|
||||
#define SSLv3_client_method yaSSLv3_client_method
|
||||
#define TLSv1_server_method yaTLSv1_server_method
|
||||
#define TLSv1_client_method yaTLSv1_client_method
|
||||
#define TLSv1_1_server_method yaTLSv1_1_server_method
|
||||
#define TLSv1_1_client_method yaTLSv1_1_client_method
|
||||
#define SSLv23_server_method yaSSLv23_server_method
|
||||
#define SSL_CTX_use_certificate_file yaSSL_CTX_use_certificate_file
|
||||
#define SSL_CTX_use_PrivateKey_file yaSSL_CTX_use_PrivateKey_file
|
||||
#define SSL_CTX_set_cipher_list yaSSL_CTX_set_cipher_list
|
||||
#define SSL_CTX_sess_set_cache_size yaSSL_CTX_sess_set_cache_size
|
||||
#define SSL_CTX_set_tmp_dh yaSSL_CTX_set_tmp_dh
|
||||
#define OpenSSL_add_all_algorithms yaOpenSSL_add_all_algorithms
|
||||
#define SSL_library_init yaSSL_library_init
|
||||
#define SSLeay_add_ssl_algorithms yaSSLeay_add_ssl_algorithms
|
||||
#define SSL_get_current_cipher yaSSL_get_current_cipher
|
||||
#define SSL_CIPHER_description yaSSL_CIPHER_description
|
||||
#define SSL_alert_type_string_long yaSSL_alert_type_string_long
|
||||
#define SSL_alert_desc_string_long yaSSL_alert_desc_string_long
|
||||
#define SSL_state_string_long yaSSL_state_string_long
|
||||
#define EVP_md5 yaEVP_md5
|
||||
#define EVP_des_ede3_cbc yaEVP_des_ede3_cbc
|
||||
#define EVP_BytesToKey yaEVP_BytesToKey
|
||||
#define DES_set_key_unchecked yaDES_set_key_unchecked
|
||||
#define DES_ede3_cbc_encrypt yaDES_ede3_cbc_encrypt
|
||||
#define RAND_screen yaRAND_screen
|
||||
#define RAND_file_name yaRAND_file_name
|
||||
#define RAND_write_file yaRAND_write_file
|
||||
#define RAND_load_file yaRAND_load_file
|
||||
#define RAND_status yaRAND_status
|
||||
#define RAND_bytes yaRAND_bytes
|
||||
#define DES_set_key yaDES_set_key
|
||||
#define DES_set_odd_parity yaDES_set_odd_parity
|
||||
#define DES_ecb_encrypt yaDES_ecb_encrypt
|
||||
#define SSL_CTX_set_default_passwd_cb_userdata yaSSL_CTX_set_default_passwd_cb_userdata
|
||||
#define SSL_SESSION_free yaSSL_SESSION_free
|
||||
#define SSL_peek yaSSL_peek
|
||||
#define SSL_get_certificate yaSSL_get_certificate
|
||||
#define SSL_get_privatekey yaSSL_get_privatekey
|
||||
#define X509_get_pubkey yaX509_get_pubkey
|
||||
#define EVP_PKEY_copy_parameters yaEVP_PKEY_copy_parameters
|
||||
#define EVP_PKEY_free yaEVP_PKEY_free
|
||||
#define ERR_error_string_n yaERR_error_string_n
|
||||
#define ERR_free_strings yaERR_free_strings
|
||||
#define EVP_cleanup yaEVP_cleanup
|
||||
#define X509_get_ext_d2i yaX509_get_ext_d2i
|
||||
#define GENERAL_NAMES_free yaGENERAL_NAMES_free
|
||||
#define sk_GENERAL_NAME_num yask_GENERAL_NAME_num
|
||||
#define sk_GENERAL_NAME_value yask_GENERAL_NAME_value
|
||||
#define ASN1_STRING_data yaASN1_STRING_data
|
||||
#define ASN1_STRING_length yaASN1_STRING_length
|
||||
#define ASN1_STRING_type yaASN1_STRING_type
|
||||
#define X509_NAME_get_index_by_NID yaX509_NAME_get_index_by_NID
|
||||
#define X509_NAME_ENTRY_get_data yaX509_NAME_ENTRY_get_data
|
||||
#define X509_NAME_get_entry yaX509_NAME_get_entry
|
||||
#define ASN1_STRING_to_UTF8 yaASN1_STRING_to_UTF8
|
||||
#define SSLv23_client_method yaSSLv23_client_method
|
||||
#define SSLv2_client_method yaSSLv2_client_method
|
||||
#define SSL_get1_session yaSSL_get1_session
|
||||
#define X509_get_notBefore yaX509_get_notBefore
|
||||
#define X509_get_notAfter yaX509_get_notAfter
|
||||
#define MD4_Init yaMD4_Init
|
||||
#define MD4_Update yaMD4_Update
|
||||
#define MD4_Final yaMD4_Final
|
||||
#define MD5_Init yaMD5_Init
|
||||
#define MD5_Update yaMD5_Update
|
||||
#define MD5_Final yaMD5_Final
|
||||
#define SSL_set_compression yaSSL_set_compression
|
||||
@@ -0,0 +1,2 @@
|
||||
/* rand.h for openSSL */
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/* rsa.h for openSSL */
|
||||
|
||||
|
||||
#ifndef yaSSL_rsa_h__
|
||||
#define yaSSL_rsa_h__
|
||||
|
||||
enum { RSA_F4 = 1 };
|
||||
|
||||
|
||||
#endif /* yaSSL_rsa_h__ */
|
||||
@@ -0,0 +1 @@
|
||||
/* sha.h for openvpn */
|
||||
+554
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* ssl.h defines openssl compatibility layer
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef yaSSL_openssl_h__
|
||||
#define yaSSL_openssl_h__
|
||||
|
||||
#ifdef YASSL_PREFIX
|
||||
#include "prefix_ssl.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* ERR_print fp */
|
||||
#include "opensslv.h" /* for version number */
|
||||
#include "rsa.h"
|
||||
|
||||
|
||||
#define YASSL_VERSION "1.7.2"
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void yaSSL_CleanUp(); /* call once at end of application use to
|
||||
free static singleton memory holders,
|
||||
not a leak per se, but helpful when
|
||||
looking for them */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !defined(YASSL_MYSQL_COMPATIBLE)
|
||||
namespace yaSSL {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#undef X509_NAME /* wincrypt.h clash */
|
||||
|
||||
#if defined(__cplusplus) && !defined(YASSL_MYSQL_COMPATIBLE)
|
||||
class SSL;
|
||||
class SSL_SESSION;
|
||||
class SSL_METHOD;
|
||||
class SSL_CTX;
|
||||
class SSL_CIPHER;
|
||||
|
||||
class RSA;
|
||||
|
||||
class X509;
|
||||
class X509_NAME;
|
||||
#else
|
||||
typedef struct SSL SSL;
|
||||
typedef struct SSL_SESSION SSL_SESSION;
|
||||
typedef struct SSL_METHOD SSL_METHOD;
|
||||
typedef struct SSL_CTX SSL_CTX;
|
||||
typedef struct SSL_CIPHER SSL_CIPHER;
|
||||
|
||||
typedef struct RSA RSA;
|
||||
|
||||
typedef struct X509 X509;
|
||||
typedef struct X509_NAME X509_NAME;
|
||||
#endif
|
||||
|
||||
|
||||
/* Big Number stuff, different file? */
|
||||
typedef struct BIGNUM BIGNUM;
|
||||
|
||||
BIGNUM *BN_bin2bn(const unsigned char*, int, BIGNUM*);
|
||||
|
||||
|
||||
/* Diffie-Hellman stuff, different file? */
|
||||
/* mySQL deferences to set group parameters */
|
||||
typedef struct DH {
|
||||
BIGNUM* p;
|
||||
BIGNUM* g;
|
||||
} DH;
|
||||
|
||||
DH* DH_new(void);
|
||||
void DH_free(DH*);
|
||||
|
||||
/* RSA stuff */
|
||||
|
||||
void RSA_free(RSA*);
|
||||
RSA* RSA_generate_key(int, unsigned long, void(*)(int, int, void*), void*);
|
||||
|
||||
|
||||
/* X509 stuff, different file? */
|
||||
|
||||
typedef struct X509_STORE X509_STORE;
|
||||
typedef struct X509_LOOKUP X509_LOOKUP;
|
||||
typedef struct X509_OBJECT { char c; } X509_OBJECT;
|
||||
typedef struct X509_CRL X509_CRL;
|
||||
typedef struct X509_REVOKED X509_REVOKED;
|
||||
typedef struct X509_LOOKUP_METHOD X509_LOOKUP_METHOD;
|
||||
|
||||
|
||||
void X509_free(X509*);
|
||||
|
||||
|
||||
/* bio stuff */
|
||||
typedef struct BIO BIO;
|
||||
|
||||
/* ASN stuff */
|
||||
|
||||
|
||||
|
||||
/* because mySQL dereferences to use error and current_cert, even after calling
|
||||
* get functions for local references */
|
||||
typedef struct X509_STORE_CTX {
|
||||
int error;
|
||||
int error_depth;
|
||||
X509* current_cert;
|
||||
} X509_STORE_CTX;
|
||||
|
||||
|
||||
|
||||
X509* X509_STORE_CTX_get_current_cert(X509_STORE_CTX*);
|
||||
int X509_STORE_CTX_get_error(X509_STORE_CTX*);
|
||||
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX*);
|
||||
|
||||
char* X509_NAME_oneline(X509_NAME*, char*, int);
|
||||
X509_NAME* X509_get_issuer_name(X509*);
|
||||
X509_NAME* X509_get_subject_name(X509*);
|
||||
const char* X509_verify_cert_error_string(long);
|
||||
|
||||
int X509_LOOKUP_add_dir(X509_LOOKUP*, const char*, long);
|
||||
int X509_LOOKUP_load_file(X509_LOOKUP*, const char*, long);
|
||||
X509_LOOKUP_METHOD* X509_LOOKUP_hash_dir(void);
|
||||
X509_LOOKUP_METHOD* X509_LOOKUP_file(void);
|
||||
|
||||
X509_LOOKUP* X509_STORE_add_lookup(X509_STORE*, X509_LOOKUP_METHOD*);
|
||||
X509_STORE* X509_STORE_new(void);
|
||||
int X509_STORE_get_by_subject(X509_STORE_CTX*, int, X509_NAME*,
|
||||
X509_OBJECT*);
|
||||
|
||||
|
||||
|
||||
|
||||
enum { /* X509 Constants */
|
||||
X509_V_OK = 0,
|
||||
X509_V_ERR_CERT_CHAIN_TOO_LONG = 1,
|
||||
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2,
|
||||
X509_V_ERR_CERT_NOT_YET_VALID = 3,
|
||||
X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 4,
|
||||
X509_V_ERR_CERT_HAS_EXPIRED = 5,
|
||||
X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 6,
|
||||
X509_FILETYPE_PEM = 7,
|
||||
X509_LU_X509 = 8,
|
||||
X509_LU_CRL = 9,
|
||||
X509_V_ERR_CRL_SIGNATURE_FAILURE = 10,
|
||||
X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 11,
|
||||
X509_V_ERR_CRL_HAS_EXPIRED = 12,
|
||||
X509_V_ERR_CERT_REVOKED = 13,
|
||||
X509_V_FLAG_CRL_CHECK = 14,
|
||||
X509_V_FLAG_CRL_CHECK_ALL = 15
|
||||
};
|
||||
|
||||
|
||||
/* Error stuff, could move to yassl_error */
|
||||
unsigned long ERR_get_error_line_data(const char**, int*, const char**, int *);
|
||||
void ERR_print_errors_fp(FILE*);
|
||||
char* ERR_error_string(unsigned long,char*);
|
||||
void ERR_remove_state(unsigned long);
|
||||
unsigned long ERR_get_error(void);
|
||||
unsigned long ERR_peek_error(void);
|
||||
int ERR_GET_REASON(int);
|
||||
|
||||
|
||||
enum { /* ERR Constants */
|
||||
ERR_TXT_STRING = 1,
|
||||
EVP_R_BAD_DECRYPT = 2
|
||||
};
|
||||
|
||||
/*
|
||||
Allow type used by SSL_set_fd to be changed, default to int
|
||||
in order to be compatible with OpenSSL
|
||||
*/
|
||||
#ifndef YASSL_SOCKET_T_DEFINED
|
||||
typedef int YASSL_SOCKET_T;
|
||||
#endif
|
||||
|
||||
SSL_CTX* SSL_CTX_new(SSL_METHOD*);
|
||||
SSL* SSL_new(SSL_CTX*);
|
||||
int SSL_set_fd (SSL*, YASSL_SOCKET_T);
|
||||
YASSL_SOCKET_T SSL_get_fd(const SSL*);
|
||||
int SSL_connect(SSL*); /* if you get an error from connect
|
||||
see note at top of REAMDE */
|
||||
int SSL_write(SSL*, const void*, int);
|
||||
int SSL_read(SSL*, void*, int);
|
||||
int SSL_accept(SSL*);
|
||||
void SSL_CTX_free(SSL_CTX*);
|
||||
void SSL_free(SSL*);
|
||||
int SSL_clear(SSL*);
|
||||
int SSL_shutdown(SSL*);
|
||||
|
||||
void SSL_set_connect_state(SSL*);
|
||||
void SSL_set_accept_state(SSL*);
|
||||
int SSL_do_handshake(SSL*);
|
||||
|
||||
const char* SSL_get_cipher(SSL*);
|
||||
const char* SSL_get_cipher_name(SSL*); /* uses SSL_get_cipher */
|
||||
char* SSL_get_shared_ciphers(SSL*, char*, int);
|
||||
const char* SSL_get_cipher_list(SSL*, int);
|
||||
const char* SSL_get_version(SSL*);
|
||||
const char* SSLeay_version(int);
|
||||
|
||||
int SSL_get_error(SSL*, int);
|
||||
void SSL_load_error_strings(void);
|
||||
|
||||
int SSL_set_session(SSL *ssl, SSL_SESSION *session);
|
||||
SSL_SESSION* SSL_get_session(SSL* ssl);
|
||||
void SSL_flush_sessions(SSL_CTX *ctx, long tm);
|
||||
long SSL_SESSION_set_timeout(SSL_SESSION*, long);
|
||||
long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode);
|
||||
X509* SSL_get_peer_certificate(SSL*);
|
||||
long SSL_get_verify_result(SSL*);
|
||||
|
||||
|
||||
typedef int (*VerifyCallback)(int, X509_STORE_CTX*);
|
||||
typedef int (*pem_password_cb)(char*, int, int, void*);
|
||||
|
||||
void SSL_CTX_set_verify(SSL_CTX*, int, VerifyCallback verify_callback);
|
||||
int SSL_CTX_load_verify_locations(SSL_CTX*, const char*, const char*);
|
||||
int SSL_CTX_set_default_verify_paths(SSL_CTX*);
|
||||
int SSL_CTX_check_private_key(SSL_CTX*);
|
||||
int SSL_CTX_set_session_id_context(SSL_CTX*, const unsigned char*,
|
||||
unsigned int);
|
||||
|
||||
void SSL_CTX_set_tmp_rsa_callback(SSL_CTX*, RSA*(*)(SSL*, int, int));
|
||||
long SSL_CTX_set_options(SSL_CTX*, long);
|
||||
long SSL_CTX_set_session_cache_mode(SSL_CTX*, long);
|
||||
long SSL_CTX_set_timeout(SSL_CTX*, long);
|
||||
int SSL_CTX_use_certificate_chain_file(SSL_CTX*, const char*);
|
||||
void SSL_CTX_set_default_passwd_cb(SSL_CTX*, pem_password_cb);
|
||||
int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX*, const char*, int);
|
||||
void SSL_CTX_set_info_callback(SSL_CTX*, void (*)());
|
||||
|
||||
long SSL_CTX_sess_accept(SSL_CTX*);
|
||||
long SSL_CTX_sess_connect(SSL_CTX*);
|
||||
long SSL_CTX_sess_accept_good(SSL_CTX*);
|
||||
long SSL_CTX_sess_connect_good(SSL_CTX*);
|
||||
long SSL_CTX_sess_accept_renegotiate(SSL_CTX*);
|
||||
long SSL_CTX_sess_connect_renegotiate(SSL_CTX*);
|
||||
long SSL_CTX_sess_hits(SSL_CTX*);
|
||||
long SSL_CTX_sess_cb_hits(SSL_CTX*);
|
||||
long SSL_CTX_sess_cache_full(SSL_CTX*);
|
||||
long SSL_CTX_sess_misses(SSL_CTX*);
|
||||
long SSL_CTX_sess_timeouts(SSL_CTX*);
|
||||
long SSL_CTX_sess_number(SSL_CTX*);
|
||||
long SSL_CTX_sess_get_cache_size(SSL_CTX*);
|
||||
|
||||
int SSL_CTX_get_verify_mode(SSL_CTX*);
|
||||
int SSL_get_verify_mode(SSL*);
|
||||
int SSL_CTX_get_verify_depth(SSL_CTX*);
|
||||
int SSL_get_verify_depth(SSL*);
|
||||
|
||||
long SSL_get_default_timeout(SSL*);
|
||||
long SSL_CTX_get_session_cache_mode(SSL_CTX*);
|
||||
int SSL_session_reused(SSL*);
|
||||
|
||||
int SSL_set_rfd(SSL*, int);
|
||||
int SSL_set_wfd(SSL*, int);
|
||||
void SSL_set_shutdown(SSL*, int);
|
||||
void SSL_set_quiet_shutdown(SSL *ssl,int mode);
|
||||
int SSL_get_quiet_shutdown(SSL *ssl);
|
||||
|
||||
int SSL_want_read(SSL*);
|
||||
int SSL_want_write(SSL*);
|
||||
|
||||
int SSL_pending(SSL*);
|
||||
|
||||
|
||||
enum { /* ssl Constants */
|
||||
SSL_WOULD_BLOCK = -8,
|
||||
SSL_BAD_STAT = -7,
|
||||
SSL_BAD_PATH = -6,
|
||||
SSL_BAD_FILETYPE = -5,
|
||||
SSL_BAD_FILE = -4,
|
||||
SSL_NOT_IMPLEMENTED = -3,
|
||||
SSL_UNKNOWN = -2,
|
||||
SSL_FATAL_ERROR = -1,
|
||||
SSL_NORMAL_SHUTDOWN = 0,
|
||||
SSL_ERROR_NONE = 0, /* for most functions */
|
||||
SSL_FAILURE = 0, /* for some functions */
|
||||
SSL_SUCCESS = 1,
|
||||
|
||||
SSL_FILETYPE_ASN1 = 10,
|
||||
SSL_FILETYPE_PEM = 11,
|
||||
SSL_FILETYPE_DEFAULT = 10, /* ASN1 */
|
||||
|
||||
SSL_VERIFY_NONE = 0,
|
||||
SSL_VERIFY_PEER = 1,
|
||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2,
|
||||
SSL_VERIFY_CLIENT_ONCE = 4,
|
||||
|
||||
SSL_SESS_CACHE_OFF = 30,
|
||||
SSL_SESS_CACHE_CLIENT = 31,
|
||||
SSL_SESS_CACHE_SERVER = 32,
|
||||
SSL_SESS_CACHE_BOTH = 33,
|
||||
SSL_SESS_CACHE_NO_AUTO_CLEAR = 34,
|
||||
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP = 35,
|
||||
|
||||
SSL_OP_MICROSOFT_SESS_ID_BUG = 50,
|
||||
SSL_OP_NETSCAPE_CHALLENGE_BUG = 51,
|
||||
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 52,
|
||||
SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 53,
|
||||
SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 54,
|
||||
SSL_OP_MSIE_SSLV2_RSA_PADDING = 55,
|
||||
SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 56,
|
||||
SSL_OP_TLS_D5_BUG = 57,
|
||||
SSL_OP_TLS_BLOCK_PADDING_BUG = 58,
|
||||
SSL_OP_TLS_ROLLBACK_BUG = 59,
|
||||
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 60,
|
||||
SSL_OP_ALL = 61,
|
||||
SSL_OP_SINGLE_DH_USE = 62,
|
||||
SSL_OP_EPHEMERAL_RSA = 63,
|
||||
SSL_OP_NO_SSLv2 = 64,
|
||||
SSL_OP_NO_SSLv3 = 65,
|
||||
SSL_OP_NO_TLSv1 = 66,
|
||||
SSL_OP_PKCS1_CHECK_1 = 67,
|
||||
SSL_OP_PKCS1_CHECK_2 = 68,
|
||||
SSL_OP_NETSCAPE_CA_DN_BUG = 69,
|
||||
SSL_OP_NON_EXPORT_FIRST = 70,
|
||||
SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 71,
|
||||
|
||||
SSL_ERROR_WANT_READ = 80,
|
||||
SSL_ERROR_WANT_WRITE = 81,
|
||||
SSL_ERROR_SYSCALL = 82,
|
||||
SSL_ERROR_WANT_X509_LOOKUP = 83,
|
||||
SSL_ERROR_ZERO_RETURN = 84,
|
||||
SSL_ERROR_SSL = 85,
|
||||
|
||||
SSL_SENT_SHUTDOWN = 90,
|
||||
SSL_RECEIVED_SHUTDOWN = 91,
|
||||
SSL_CB_LOOP = 92,
|
||||
SSL_ST_CONNECT = 93,
|
||||
SSL_ST_ACCEPT = 94,
|
||||
SSL_CB_ALERT = 95,
|
||||
SSL_CB_READ = 96,
|
||||
SSL_CB_HANDSHAKE_DONE = 97
|
||||
|
||||
};
|
||||
|
||||
|
||||
SSL_METHOD *SSLv3_method(void);
|
||||
SSL_METHOD *SSLv3_server_method(void);
|
||||
SSL_METHOD *SSLv3_client_method(void);
|
||||
SSL_METHOD *TLSv1_server_method(void);
|
||||
SSL_METHOD *TLSv1_client_method(void);
|
||||
SSL_METHOD *TLSv1_1_server_method(void);
|
||||
SSL_METHOD *TLSv1_1_client_method(void);
|
||||
SSL_METHOD *SSLv23_server_method(void);
|
||||
|
||||
int SSL_CTX_use_certificate_file(SSL_CTX*, const char*, int);
|
||||
int SSL_CTX_use_PrivateKey_file(SSL_CTX*, const char*, int);
|
||||
int SSL_CTX_set_cipher_list(SSL_CTX*, const char*);
|
||||
|
||||
long SSL_CTX_sess_set_cache_size(SSL_CTX*, long);
|
||||
long SSL_CTX_set_tmp_dh(SSL_CTX*, DH*);
|
||||
|
||||
void OpenSSL_add_all_algorithms(void);
|
||||
int SSL_library_init();
|
||||
int SSLeay_add_ssl_algorithms(void);
|
||||
|
||||
|
||||
SSL_CIPHER* SSL_get_current_cipher(SSL*);
|
||||
char* SSL_CIPHER_description(SSL_CIPHER*, char*, int);
|
||||
|
||||
|
||||
char* SSL_alert_type_string_long(int);
|
||||
char* SSL_alert_desc_string_long(int);
|
||||
char* SSL_state_string_long(SSL*);
|
||||
|
||||
|
||||
/* EVP stuff, des and md5, different file? */
|
||||
typedef char EVP_MD;
|
||||
|
||||
typedef char EVP_CIPHER;
|
||||
|
||||
typedef struct EVP_PKEY EVP_PKEY;
|
||||
|
||||
typedef unsigned char DES_cblock[8];
|
||||
typedef const DES_cblock const_DES_cblock;
|
||||
typedef DES_cblock DES_key_schedule;
|
||||
|
||||
enum {
|
||||
DES_ENCRYPT = 1,
|
||||
DES_DECRYPT = 0
|
||||
};
|
||||
|
||||
const EVP_MD* EVP_md5(void);
|
||||
const EVP_CIPHER* EVP_des_ede3_cbc(void);
|
||||
|
||||
typedef unsigned char opaque;
|
||||
|
||||
int EVP_BytesToKey(const EVP_CIPHER*, const EVP_MD*, const opaque*,
|
||||
const opaque*, int, int, opaque*, opaque*);
|
||||
|
||||
void DES_set_key_unchecked(const_DES_cblock*, DES_key_schedule*);
|
||||
void DES_ede3_cbc_encrypt(const opaque*, opaque*, long, DES_key_schedule*,
|
||||
DES_key_schedule*, DES_key_schedule*, DES_cblock*, int);
|
||||
|
||||
|
||||
/* RAND stuff */
|
||||
void RAND_screen(void);
|
||||
const char* RAND_file_name(char*, size_t);
|
||||
int RAND_write_file(const char*);
|
||||
int RAND_load_file(const char*, long);
|
||||
|
||||
|
||||
/* for libcurl */
|
||||
int RAND_status(void);
|
||||
int RAND_bytes(unsigned char* buf, int num);
|
||||
|
||||
int DES_set_key(const_DES_cblock*, DES_key_schedule*);
|
||||
void DES_set_odd_parity(DES_cblock*);
|
||||
void DES_ecb_encrypt(DES_cblock*, DES_cblock*, DES_key_schedule*, int);
|
||||
|
||||
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX*, void* userdata);
|
||||
void SSL_SESSION_free(SSL_SESSION* session);
|
||||
int SSL_peek(SSL* ssl, void* buf, int num);
|
||||
|
||||
X509* SSL_get_certificate(SSL* ssl);
|
||||
EVP_PKEY* SSL_get_privatekey(SSL* ssl);
|
||||
EVP_PKEY* X509_get_pubkey(X509* x);
|
||||
|
||||
int EVP_PKEY_copy_parameters(EVP_PKEY* to, const EVP_PKEY* from);
|
||||
void EVP_PKEY_free(EVP_PKEY* pkey);
|
||||
void ERR_error_string_n(unsigned long e, char *buf, size_t len);
|
||||
void ERR_free_strings(void);
|
||||
void EVP_cleanup(void);
|
||||
|
||||
void* X509_get_ext_d2i(X509* x, int nid, int* crit, int* idx);
|
||||
|
||||
#define GEN_IPADD 7
|
||||
#define NID_subject_alt_name 85
|
||||
#define STACK_OF(x) x
|
||||
|
||||
|
||||
/* defined here because libcurl dereferences */
|
||||
typedef struct ASN1_STRING {
|
||||
int type;
|
||||
int length;
|
||||
unsigned char* data;
|
||||
} ASN1_STRING;
|
||||
|
||||
|
||||
typedef struct GENERAL_NAME {
|
||||
int type;
|
||||
union {
|
||||
ASN1_STRING* ia5;
|
||||
} d;
|
||||
} GENERAL_NAME;
|
||||
|
||||
void GENERAL_NAMES_free(STACK_OF(GENERAL_NAME) *x);
|
||||
|
||||
int sk_GENERAL_NAME_num(STACK_OF(GENERAL_NAME) *x);
|
||||
GENERAL_NAME* sk_GENERAL_NAME_value(STACK_OF(GENERAL_NAME) *x, int i);
|
||||
|
||||
|
||||
unsigned char* ASN1_STRING_data(ASN1_STRING* x);
|
||||
int ASN1_STRING_length(ASN1_STRING* x);
|
||||
int ASN1_STRING_type(ASN1_STRING *x);
|
||||
|
||||
typedef ASN1_STRING X509_NAME_ENTRY;
|
||||
|
||||
int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos);
|
||||
|
||||
ASN1_STRING* X509_NAME_ENTRY_get_data(X509_NAME_ENTRY* ne);
|
||||
X509_NAME_ENTRY* X509_NAME_get_entry(X509_NAME* name, int loc);
|
||||
|
||||
#define OPENSSL_malloc(x) malloc(x)
|
||||
#define OPENSSL_free(x) free(x)
|
||||
|
||||
int ASN1_STRING_to_UTF8(unsigned char** out, ASN1_STRING* in);
|
||||
|
||||
SSL_METHOD* SSLv23_client_method(void); /* doesn't actually roll back */
|
||||
SSL_METHOD* SSLv2_client_method(void); /* will never work, no v 2 */
|
||||
|
||||
|
||||
SSL_SESSION* SSL_get1_session(SSL* ssl); /* what's ref count */
|
||||
|
||||
|
||||
#define CRYPTO_free(x) free(x)
|
||||
#define ASN1_TIME ASN1_STRING
|
||||
|
||||
ASN1_TIME* X509_get_notBefore(X509* x);
|
||||
ASN1_TIME* X509_get_notAfter(X509* x);
|
||||
|
||||
|
||||
#define ASN1_UTCTIME ASN1_STRING
|
||||
#define NID_commonName 13
|
||||
#define V_ASN1_UTF8STRING 12
|
||||
#define GEN_DNS 2
|
||||
|
||||
#define CERTFICATE_ERROR 0x14090086 /* SSLv3 error */
|
||||
|
||||
|
||||
typedef struct MD4_CTX {
|
||||
int buffer[32]; /* big enough to hold, check size in Init */
|
||||
} MD4_CTX;
|
||||
|
||||
void MD4_Init(MD4_CTX*);
|
||||
void MD4_Update(MD4_CTX*, const void*, unsigned long);
|
||||
void MD4_Final(unsigned char*, MD4_CTX*);
|
||||
|
||||
|
||||
typedef struct MD5_CTX {
|
||||
int buffer[32]; /* big enough to hold, check size in Init */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5_Init(MD5_CTX*);
|
||||
void MD5_Update(MD5_CTX*, const void*, unsigned long);
|
||||
void MD5_Final(unsigned char*, MD5_CTX*);
|
||||
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
|
||||
|
||||
#define SSL_DEFAULT_CIPHER_LIST "" /* default all */
|
||||
|
||||
|
||||
/* yaSSL adds */
|
||||
int SSL_set_compression(SSL*); /* turn on yaSSL zlib compression */
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(__cplusplus) && !defined(YASSL_MYSQL_COMPATIBLE)
|
||||
} /* namespace */
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* yaSSL_openssl_h__ */
|
||||
@@ -0,0 +1 @@
|
||||
/* x509.h for libcurl */
|
||||
@@ -0,0 +1 @@
|
||||
/* x509v3.h for libcurl */
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* The socket wrapper header defines a Socket class that hides the differences
|
||||
* between Berkely style sockets and Windows sockets, allowing transparent TCP
|
||||
* access.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_SOCKET_WRAPPER_HPP
|
||||
#define yaSSL_SOCKET_WRAPPER_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef SOCKET socket_t;
|
||||
#else
|
||||
typedef int socket_t;
|
||||
const socket_t INVALID_SOCKET = -1;
|
||||
const int SD_RECEIVE = 0;
|
||||
const int SD_SEND = 1;
|
||||
const int SD_BOTH = 2;
|
||||
const int SOCKET_ERROR = -1;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
|
||||
// Wraps Windows Sockets and BSD Sockets
|
||||
class Socket {
|
||||
socket_t socket_; // underlying socket descriptor
|
||||
bool wouldBlock_; // if non-blocking data, for last read
|
||||
bool nonBlocking_; // is option set
|
||||
public:
|
||||
explicit Socket(socket_t s = INVALID_SOCKET);
|
||||
~Socket();
|
||||
|
||||
void set_fd(socket_t s);
|
||||
uint get_ready() const;
|
||||
socket_t get_fd() const;
|
||||
|
||||
uint send(const byte* buf, unsigned int len, int flags = 0) const;
|
||||
uint receive(byte* buf, unsigned int len, int flags = 0);
|
||||
|
||||
bool wait();
|
||||
bool WouldBlock() const;
|
||||
bool IsNonBlocking() const;
|
||||
|
||||
void closeSocket();
|
||||
void shutDown(int how = SD_SEND);
|
||||
|
||||
static int get_lastError();
|
||||
static void set_lastError(int error);
|
||||
private:
|
||||
Socket(const Socket&); // hide copy
|
||||
Socket& operator= (const Socket&); // and assign
|
||||
};
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_SOCKET_WRAPPER_HPP
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* timer.hpp provides a high res and low res timers
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_TIMER_HPP
|
||||
#define yaSSL_TIMER_HPP
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
typedef double timer_d;
|
||||
typedef unsigned int uint;
|
||||
|
||||
|
||||
|
||||
timer_d timer();
|
||||
uint lowResTimer();
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
#endif // yaSSL_TIMER_HPP
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL externel header defines yaSSL API
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_EXT_HPP
|
||||
#define yaSSL_EXT_HPP
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef unsigned int SOCKET_T;
|
||||
#else
|
||||
typedef int SOCKET_T;
|
||||
#endif
|
||||
|
||||
|
||||
class Client {
|
||||
public:
|
||||
Client();
|
||||
~Client();
|
||||
|
||||
// basics
|
||||
int Connect(SOCKET_T);
|
||||
int Write(const void*, int);
|
||||
int Read(void*, int);
|
||||
|
||||
// options
|
||||
void SetCA(const char*);
|
||||
void SetCert(const char*);
|
||||
void SetKey(const char*);
|
||||
private:
|
||||
struct ClientImpl;
|
||||
ClientImpl* pimpl_;
|
||||
|
||||
Client(const Client&); // hide copy
|
||||
Client& operator=(const Client&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class Server {
|
||||
public:
|
||||
Server();
|
||||
~Server();
|
||||
|
||||
// basics
|
||||
int Accept(SOCKET_T);
|
||||
int Write(const void*, int);
|
||||
int Read(void*, int);
|
||||
|
||||
// options
|
||||
void SetCA(const char*);
|
||||
void SetCert(const char*);
|
||||
void SetKey(const char*);
|
||||
private:
|
||||
struct ServerImpl;
|
||||
ServerImpl* pimpl_;
|
||||
|
||||
Server(const Server&); // hide copy
|
||||
Server& operator=(const Server&); // and assign
|
||||
};
|
||||
|
||||
|
||||
} // namespace yaSSL
|
||||
#endif // yaSSL_EXT_HPP
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL error header defines error codes and an exception class
|
||||
*/
|
||||
|
||||
#ifndef yaSSL_ERROR_HPP
|
||||
#define yaSSL_ERROR_HPP
|
||||
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
enum YasslError {
|
||||
no_error = 0,
|
||||
|
||||
// 10 - 47 from AlertDescription, 0 also close_notify
|
||||
|
||||
range_error = 101,
|
||||
realloc_error = 102,
|
||||
factory_error = 103,
|
||||
unknown_cipher = 104,
|
||||
prefix_error = 105,
|
||||
record_layer = 106,
|
||||
handshake_layer = 107,
|
||||
out_of_order = 108,
|
||||
bad_input = 109,
|
||||
match_error = 110,
|
||||
no_key_file = 111,
|
||||
verify_error = 112,
|
||||
send_error = 113,
|
||||
receive_error = 114,
|
||||
certificate_error = 115,
|
||||
privateKey_error = 116,
|
||||
badVersion_error = 117,
|
||||
compress_error = 118,
|
||||
decompress_error = 119,
|
||||
pms_version_error = 120
|
||||
|
||||
// !!!! add error message to .cpp !!!!
|
||||
|
||||
// 1000+ from TaoCrypt error.hpp
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum Library { yaSSL_Lib = 0, CryptoLib, SocketLib };
|
||||
enum { MAX_ERROR_SZ = 80 };
|
||||
|
||||
void SetErrorString(YasslError, char*);
|
||||
|
||||
/* remove for now, if go back to exceptions use this wrapper
|
||||
// Base class for all yaSSL exceptions
|
||||
class Error : public mySTL::runtime_error {
|
||||
YasslError error_;
|
||||
Library lib_;
|
||||
public:
|
||||
explicit Error(const char* s = "", YasslError e = no_error,
|
||||
Library l = yaSSL_Lib);
|
||||
|
||||
YasslError get_number() const;
|
||||
Library get_lib() const;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_ERROR_HPP
|
||||
+748
@@ -0,0 +1,748 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* yaSSL implementation header defines all strucutres from the SSL.v3
|
||||
* specification "draft-freier-ssl-version3-02.txt"
|
||||
* all page citations refer to this document unless otherwise noted.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_IMP_HPP
|
||||
#define yaSSL_IMP_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// disable truncated debug symbols
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
#include "yassl_types.hpp"
|
||||
#include "factory.hpp"
|
||||
#include STL_LIST_FILE
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
class SSL; // forward decls
|
||||
class input_buffer;
|
||||
class output_buffer;
|
||||
|
||||
|
||||
struct ProtocolVersion {
|
||||
uint8 major_;
|
||||
uint8 minor_; // major and minor SSL/TLS version numbers
|
||||
|
||||
ProtocolVersion(uint8 maj = 3, uint8 min = 0);
|
||||
};
|
||||
|
||||
|
||||
// Record Layer Header for PlainText, Compressed, and CipherText
|
||||
struct RecordLayerHeader {
|
||||
ContentType type_;
|
||||
ProtocolVersion version_;
|
||||
uint16 length_; // should not exceed 2^14
|
||||
};
|
||||
|
||||
|
||||
// base for all messages
|
||||
struct Message : public virtual_base {
|
||||
virtual input_buffer& set(input_buffer&) =0;
|
||||
virtual output_buffer& get(output_buffer&) const =0;
|
||||
|
||||
virtual void Process(input_buffer&, SSL&) =0;
|
||||
virtual ContentType get_type() const =0;
|
||||
virtual uint16 get_length() const =0;
|
||||
|
||||
virtual ~Message() {}
|
||||
};
|
||||
|
||||
|
||||
class ChangeCipherSpec : public Message {
|
||||
CipherChoice type_;
|
||||
public:
|
||||
ChangeCipherSpec();
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, ChangeCipherSpec&);
|
||||
friend output_buffer& operator<<(output_buffer&, const ChangeCipherSpec&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
ContentType get_type() const;
|
||||
uint16 get_length() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
private:
|
||||
ChangeCipherSpec(const ChangeCipherSpec&); // hide copy
|
||||
ChangeCipherSpec& operator=(const ChangeCipherSpec&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Alert : public Message {
|
||||
AlertLevel level_;
|
||||
AlertDescription description_;
|
||||
public:
|
||||
Alert() {}
|
||||
Alert(AlertLevel al, AlertDescription ad);
|
||||
|
||||
ContentType get_type() const;
|
||||
uint16 get_length() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, Alert&);
|
||||
friend output_buffer& operator<<(output_buffer&, const Alert&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
private:
|
||||
Alert(const Alert&); // hide copy
|
||||
Alert& operator=(const Alert&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class Data : public Message {
|
||||
uint16 length_;
|
||||
opaque* buffer_; // read buffer used by fillData input
|
||||
const opaque* write_buffer_; // write buffer used by output operator
|
||||
public:
|
||||
Data();
|
||||
Data(uint16 len, opaque* b);
|
||||
|
||||
friend output_buffer& operator<<(output_buffer&, const Data&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
ContentType get_type() const;
|
||||
uint16 get_length() const;
|
||||
void set_length(uint16 l);
|
||||
opaque* set_buffer();
|
||||
void SetData(uint16, const opaque*);
|
||||
void Process(input_buffer&, SSL&);
|
||||
private:
|
||||
Data(const Data&); // hide copy
|
||||
Data& operator=(const Data&); // and assign
|
||||
};
|
||||
|
||||
|
||||
uint32 c24to32(const uint24); // forward form internal header
|
||||
void c32to24(uint32, uint24&);
|
||||
|
||||
|
||||
// HandShake header, same for each message type from page 20/21
|
||||
class HandShakeHeader : public Message {
|
||||
HandShakeType type_;
|
||||
uint24 length_; // length of message
|
||||
public:
|
||||
HandShakeHeader() {}
|
||||
|
||||
ContentType get_type() const;
|
||||
uint16 get_length() const;
|
||||
HandShakeType get_handshakeType() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
|
||||
void set_type(HandShakeType hst);
|
||||
void set_length(uint32 u32);
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, HandShakeHeader&);
|
||||
friend output_buffer& operator<<(output_buffer&, const HandShakeHeader&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
private:
|
||||
HandShakeHeader(const HandShakeHeader&); // hide copy
|
||||
HandShakeHeader& operator=(const HandShakeHeader&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// Base Class for all handshake messages
|
||||
class HandShakeBase : public virtual_base {
|
||||
int length_;
|
||||
public:
|
||||
int get_length() const;
|
||||
void set_length(int);
|
||||
|
||||
// for building buffer's type field
|
||||
virtual HandShakeType get_type() const =0;
|
||||
|
||||
// handles dispactch of proper >>
|
||||
virtual input_buffer& set(input_buffer& in) =0;
|
||||
virtual output_buffer& get(output_buffer& out) const =0;
|
||||
|
||||
virtual void Process(input_buffer&, SSL&) =0;
|
||||
|
||||
virtual ~HandShakeBase() {}
|
||||
};
|
||||
|
||||
|
||||
struct HelloRequest : public HandShakeBase {
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
void Process(input_buffer&, SSL&);
|
||||
|
||||
HandShakeType get_type() const;
|
||||
};
|
||||
|
||||
|
||||
// The Client's Hello Message from page 23
|
||||
class ClientHello : public HandShakeBase {
|
||||
ProtocolVersion client_version_;
|
||||
Random random_;
|
||||
uint8 id_len_; // session id length
|
||||
opaque session_id_[ID_LEN];
|
||||
uint16 suite_len_; // cipher suite length
|
||||
opaque cipher_suites_[MAX_SUITE_SZ];
|
||||
uint8 comp_len_; // compression length
|
||||
CompressionMethod compression_methods_;
|
||||
public:
|
||||
friend input_buffer& operator>>(input_buffer&, ClientHello&);
|
||||
friend output_buffer& operator<<(output_buffer&, const ClientHello&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
HandShakeType get_type() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
|
||||
const opaque* get_random() const;
|
||||
friend void buildClientHello(SSL&, ClientHello&);
|
||||
friend void ProcessOldClientHello(input_buffer& input, SSL& ssl);
|
||||
|
||||
ClientHello();
|
||||
ClientHello(ProtocolVersion pv, bool useCompression);
|
||||
private:
|
||||
ClientHello(const ClientHello&); // hide copy
|
||||
ClientHello& operator=(const ClientHello&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
// The Server's Hello Message from page 24
|
||||
class ServerHello : public HandShakeBase {
|
||||
ProtocolVersion server_version_;
|
||||
Random random_;
|
||||
uint8 id_len_; // session id length
|
||||
opaque session_id_[ID_LEN];
|
||||
opaque cipher_suite_[SUITE_LEN];
|
||||
CompressionMethod compression_method_;
|
||||
public:
|
||||
ServerHello(ProtocolVersion pv, bool useCompression);
|
||||
ServerHello();
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, ServerHello&);
|
||||
friend output_buffer& operator<<(output_buffer&, const ServerHello&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
HandShakeType get_type() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
|
||||
const opaque* get_random() const;
|
||||
friend void buildServerHello(SSL&, ServerHello&);
|
||||
private:
|
||||
ServerHello(const ServerHello&); // hide copy
|
||||
ServerHello& operator=(const ServerHello&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class x509;
|
||||
|
||||
// Certificate could be a chain
|
||||
class Certificate : public HandShakeBase {
|
||||
const x509* cert_;
|
||||
public:
|
||||
Certificate();
|
||||
explicit Certificate(const x509* cert);
|
||||
friend output_buffer& operator<<(output_buffer&, const Certificate&);
|
||||
|
||||
const opaque* get_buffer() const;
|
||||
|
||||
// Process handles input, needs SSL
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
HandShakeType get_type() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
private:
|
||||
Certificate(const Certificate&); // hide copy
|
||||
Certificate& operator=(const Certificate&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
// RSA Public Key
|
||||
struct ServerRSAParams {
|
||||
opaque* rsa_modulus_;
|
||||
opaque* rsa_exponent_;
|
||||
};
|
||||
|
||||
|
||||
// Ephemeral Diffie-Hellman Parameters
|
||||
class ServerDHParams {
|
||||
int pSz_;
|
||||
int gSz_;
|
||||
int pubSz_;
|
||||
opaque* p_;
|
||||
opaque* g_;
|
||||
opaque* Ys_;
|
||||
public:
|
||||
ServerDHParams();
|
||||
~ServerDHParams();
|
||||
|
||||
int get_pSize() const;
|
||||
int get_gSize() const;
|
||||
int get_pubSize() const;
|
||||
|
||||
const opaque* get_p() const;
|
||||
const opaque* get_g() const;
|
||||
const opaque* get_pub() const;
|
||||
|
||||
opaque* alloc_p(int sz);
|
||||
opaque* alloc_g(int sz);
|
||||
opaque* alloc_pub(int sz);
|
||||
private:
|
||||
ServerDHParams(const ServerDHParams&); // hide copy
|
||||
ServerDHParams& operator=(const ServerDHParams&); // and assign
|
||||
};
|
||||
|
||||
|
||||
struct ServerKeyBase : public virtual_base {
|
||||
virtual ~ServerKeyBase() {}
|
||||
virtual void build(SSL&) {}
|
||||
virtual void read(SSL&, input_buffer&) {}
|
||||
virtual int get_length() const;
|
||||
virtual opaque* get_serverKey() const;
|
||||
};
|
||||
|
||||
|
||||
// Server random number for FORTEZZA KEA
|
||||
struct Fortezza_Server : public ServerKeyBase {
|
||||
opaque r_s_[FORTEZZA_MAX];
|
||||
};
|
||||
|
||||
|
||||
struct SignatureBase : public virtual_base {
|
||||
virtual ~SignatureBase() {}
|
||||
};
|
||||
|
||||
struct anonymous_sa : public SignatureBase {};
|
||||
|
||||
|
||||
struct Hashes {
|
||||
uint8 md5_[MD5_LEN];
|
||||
uint8 sha_[SHA_LEN];
|
||||
};
|
||||
|
||||
|
||||
struct rsa_sa : public SignatureBase {
|
||||
Hashes hashes_;
|
||||
};
|
||||
|
||||
|
||||
struct dsa_sa : public SignatureBase {
|
||||
uint8 sha_[SHA_LEN];
|
||||
};
|
||||
|
||||
|
||||
// Server's Diffie-Hellman exchange
|
||||
class DH_Server : public ServerKeyBase {
|
||||
ServerDHParams parms_;
|
||||
opaque* signature_;
|
||||
|
||||
int length_; // total length of message
|
||||
opaque* keyMessage_; // total exchange message
|
||||
public:
|
||||
DH_Server();
|
||||
~DH_Server();
|
||||
|
||||
void build(SSL&);
|
||||
void read(SSL&, input_buffer&);
|
||||
int get_length() const;
|
||||
opaque* get_serverKey() const;
|
||||
private:
|
||||
DH_Server(const DH_Server&); // hide copy
|
||||
DH_Server& operator=(const DH_Server&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// Server's RSA exchange
|
||||
struct RSA_Server : public ServerKeyBase {
|
||||
ServerRSAParams params_;
|
||||
opaque* signature_; // signed rsa_sa hashes
|
||||
};
|
||||
|
||||
|
||||
class ServerKeyExchange : public HandShakeBase {
|
||||
ServerKeyBase* server_key_;
|
||||
public:
|
||||
explicit ServerKeyExchange(SSL&);
|
||||
ServerKeyExchange();
|
||||
~ServerKeyExchange();
|
||||
|
||||
void createKey(SSL&);
|
||||
void build(SSL& ssl);
|
||||
|
||||
const opaque* getKey() const;
|
||||
int getKeyLength() const;
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
friend output_buffer& operator<<(output_buffer&, const ServerKeyExchange&);
|
||||
|
||||
void Process(input_buffer&, SSL&);
|
||||
HandShakeType get_type() const;
|
||||
private:
|
||||
ServerKeyExchange(const ServerKeyExchange&); // hide copy
|
||||
ServerKeyExchange& operator=(const ServerKeyExchange&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CertificateRequest : public HandShakeBase {
|
||||
ClientCertificateType certificate_types_[CERT_TYPES];
|
||||
int typeTotal_;
|
||||
STL::list<DistinguishedName> certificate_authorities_;
|
||||
public:
|
||||
CertificateRequest();
|
||||
~CertificateRequest();
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, CertificateRequest&);
|
||||
friend output_buffer& operator<<(output_buffer&,
|
||||
const CertificateRequest&);
|
||||
|
||||
void Process(input_buffer&, SSL&);
|
||||
HandShakeType get_type() const;
|
||||
|
||||
void Build();
|
||||
private:
|
||||
CertificateRequest(const CertificateRequest&); // hide copy
|
||||
CertificateRequest& operator=(const CertificateRequest&); // and assign
|
||||
};
|
||||
|
||||
|
||||
struct ServerHelloDone : public HandShakeBase {
|
||||
ServerHelloDone();
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
void Process(input_buffer& input, SSL& ssl);
|
||||
|
||||
HandShakeType get_type() const;
|
||||
};
|
||||
|
||||
|
||||
struct PreMasterSecret {
|
||||
opaque random_[SECRET_LEN]; // first two bytes Protocol Version
|
||||
};
|
||||
|
||||
|
||||
struct ClientKeyBase : public virtual_base {
|
||||
virtual ~ClientKeyBase() {}
|
||||
virtual void build(SSL&) {}
|
||||
virtual void read(SSL&, input_buffer&) {}
|
||||
virtual int get_length() const;
|
||||
virtual opaque* get_clientKey() const;
|
||||
};
|
||||
|
||||
|
||||
class EncryptedPreMasterSecret : public ClientKeyBase {
|
||||
opaque* secret_;
|
||||
int length_;
|
||||
public:
|
||||
EncryptedPreMasterSecret();
|
||||
~EncryptedPreMasterSecret();
|
||||
|
||||
void build(SSL&);
|
||||
void read(SSL&, input_buffer&);
|
||||
int get_length() const;
|
||||
opaque* get_clientKey() const;
|
||||
void alloc(int sz);
|
||||
private:
|
||||
// hide copy and assign
|
||||
EncryptedPreMasterSecret(const EncryptedPreMasterSecret&);
|
||||
EncryptedPreMasterSecret& operator=(const EncryptedPreMasterSecret&);
|
||||
};
|
||||
|
||||
|
||||
// Fortezza Key Parameters from page 29
|
||||
// hard code lengths cause only used here
|
||||
struct FortezzaKeys : public ClientKeyBase {
|
||||
opaque y_c_ [128]; // client's Yc, public value
|
||||
opaque r_c_ [128]; // client's Rc
|
||||
opaque y_signature_ [40]; // DSS signed public key
|
||||
opaque wrapped_client_write_key_ [12]; // wrapped by the TEK
|
||||
opaque wrapped_server_write_key_ [12]; // wrapped by the TEK
|
||||
opaque client_write_iv_ [24];
|
||||
opaque server_write_iv_ [24];
|
||||
opaque master_secret_iv_ [24]; // IV used to encrypt preMaster
|
||||
opaque encrypted_preMasterSecret_[48]; // random & crypted by the TEK
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Diffie-Hellman public key from page 40/41
|
||||
class ClientDiffieHellmanPublic : public ClientKeyBase {
|
||||
PublicValueEncoding public_value_encoding_;
|
||||
int length_; // includes two byte length for message
|
||||
opaque* Yc_; // length + Yc_
|
||||
// dh_Yc only if explicit, otherwise sent in certificate
|
||||
enum { KEY_OFFSET = 2 };
|
||||
public:
|
||||
ClientDiffieHellmanPublic();
|
||||
~ClientDiffieHellmanPublic();
|
||||
|
||||
void build(SSL&);
|
||||
void read(SSL&, input_buffer&);
|
||||
int get_length() const;
|
||||
opaque* get_clientKey() const;
|
||||
void alloc(int sz, bool offset = false);
|
||||
private:
|
||||
// hide copy and assign
|
||||
ClientDiffieHellmanPublic(const ClientDiffieHellmanPublic&);
|
||||
ClientDiffieHellmanPublic& operator=(const ClientDiffieHellmanPublic&);
|
||||
};
|
||||
|
||||
|
||||
class ClientKeyExchange : public HandShakeBase {
|
||||
ClientKeyBase* client_key_;
|
||||
public:
|
||||
explicit ClientKeyExchange(SSL& ssl);
|
||||
ClientKeyExchange();
|
||||
~ClientKeyExchange();
|
||||
|
||||
void createKey(SSL&);
|
||||
void build(SSL& ssl);
|
||||
|
||||
const opaque* getKey() const;
|
||||
int getKeyLength() const;
|
||||
|
||||
friend output_buffer& operator<<(output_buffer&, const ClientKeyExchange&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
HandShakeType get_type() const;
|
||||
void Process(input_buffer&, SSL&);
|
||||
private:
|
||||
ClientKeyExchange(const ClientKeyExchange&); // hide copy
|
||||
ClientKeyExchange& operator=(const ClientKeyExchange&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class CertificateVerify : public HandShakeBase {
|
||||
Hashes hashes_;
|
||||
byte* signature_; // owns
|
||||
public:
|
||||
CertificateVerify();
|
||||
~CertificateVerify();
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, CertificateVerify&);
|
||||
friend output_buffer& operator<<(output_buffer&, const CertificateVerify&);
|
||||
|
||||
void Process(input_buffer&, SSL&);
|
||||
HandShakeType get_type() const;
|
||||
|
||||
void Build(SSL&);
|
||||
private:
|
||||
CertificateVerify(const CertificateVerify&); // hide copy
|
||||
CertificateVerify& operator=(const CertificateVerify&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class Finished : public HandShakeBase {
|
||||
Hashes hashes_;
|
||||
public:
|
||||
Finished();
|
||||
|
||||
uint8* set_md5();
|
||||
uint8* set_sha();
|
||||
|
||||
friend input_buffer& operator>>(input_buffer&, Finished&);
|
||||
friend output_buffer& operator<<(output_buffer&, const Finished&);
|
||||
|
||||
input_buffer& set(input_buffer& in);
|
||||
output_buffer& get(output_buffer& out) const;
|
||||
|
||||
void Process(input_buffer&, SSL&);
|
||||
|
||||
HandShakeType get_type() const;
|
||||
private:
|
||||
Finished(const Finished&); // hide copy
|
||||
Finished& operator=(const Finished&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class RandomPool; // forward for connection
|
||||
|
||||
|
||||
// SSL Connection defined on page 11
|
||||
struct Connection {
|
||||
opaque *pre_master_secret_;
|
||||
opaque master_secret_[SECRET_LEN];
|
||||
opaque client_random_[RAN_LEN];
|
||||
opaque server_random_[RAN_LEN];
|
||||
opaque sessionID_[ID_LEN];
|
||||
opaque client_write_MAC_secret_[SHA_LEN]; // sha is max size
|
||||
opaque server_write_MAC_secret_[SHA_LEN];
|
||||
opaque client_write_key_[AES_256_KEY_SZ]; // aes 256bit is max sz
|
||||
opaque server_write_key_[AES_256_KEY_SZ];
|
||||
opaque client_write_IV_[AES_IV_SZ]; // aes is max size
|
||||
opaque server_write_IV_[AES_IV_SZ];
|
||||
uint32 sequence_number_;
|
||||
uint32 peer_sequence_number_;
|
||||
uint32 pre_secret_len_; // pre master length
|
||||
bool send_server_key_; // server key exchange?
|
||||
bool master_clean_; // master secret clean?
|
||||
bool TLS_; // TLSv1 or greater
|
||||
bool TLSv1_1_; // TLSv1.1 or greater
|
||||
bool sessionID_Set_; // do we have a session
|
||||
bool compression_; // zlib compression?
|
||||
ProtocolVersion version_; // negotiated version
|
||||
ProtocolVersion chVersion_; // client hello version
|
||||
RandomPool& random_;
|
||||
|
||||
Connection(ProtocolVersion v, RandomPool& ran);
|
||||
~Connection();
|
||||
|
||||
void AllocPreSecret(uint sz);
|
||||
void CleanPreMaster();
|
||||
void CleanMaster();
|
||||
void TurnOffTLS();
|
||||
void TurnOffTLS1_1();
|
||||
private:
|
||||
Connection(const Connection&); // hide copy
|
||||
Connection& operator=(const Connection&); // and assign
|
||||
};
|
||||
|
||||
|
||||
struct Ciphers; // forward
|
||||
|
||||
|
||||
// TLSv1 Security Spec, defined on page 56 of RFC 2246
|
||||
struct Parameters {
|
||||
ConnectionEnd entity_;
|
||||
BulkCipherAlgorithm bulk_cipher_algorithm_;
|
||||
CipherType cipher_type_;
|
||||
uint8 key_size_;
|
||||
uint8 iv_size_;
|
||||
IsExportable is_exportable_;
|
||||
MACAlgorithm mac_algorithm_;
|
||||
uint8 hash_size_;
|
||||
CompressionMethod compression_algorithm_;
|
||||
KeyExchangeAlgorithm kea_; // yassl additions
|
||||
SignatureAlgorithm sig_algo_; // signature auth type
|
||||
SignatureAlgorithm verify_algo_; // cert verify auth type
|
||||
bool pending_;
|
||||
bool resumable_; // new conns by session
|
||||
uint16 encrypt_size_; // current msg encrypt sz
|
||||
Cipher suite_[SUITE_LEN]; // choosen suite
|
||||
uint8 suites_size_;
|
||||
Cipher suites_[MAX_SUITE_SZ];
|
||||
char cipher_name_[MAX_SUITE_NAME];
|
||||
char cipher_list_[MAX_CIPHERS][MAX_SUITE_NAME];
|
||||
bool removeDH_; // for server's later use
|
||||
|
||||
Parameters(ConnectionEnd, const Ciphers&, ProtocolVersion, bool haveDH);
|
||||
|
||||
void SetSuites(ProtocolVersion pv, bool removeDH = false,
|
||||
bool removeRSA = false, bool removeDSA = false);
|
||||
void SetCipherNames();
|
||||
private:
|
||||
Parameters(const Parameters&); // hide copy
|
||||
Parameters& operator=(const Parameters&); // and assing
|
||||
};
|
||||
|
||||
|
||||
input_buffer& operator>>(input_buffer&, RecordLayerHeader&);
|
||||
output_buffer& operator<<(output_buffer&, const RecordLayerHeader&);
|
||||
|
||||
input_buffer& operator>>(input_buffer&, Message&);
|
||||
output_buffer& operator<<(output_buffer&, const Message&);
|
||||
|
||||
input_buffer& operator>>(input_buffer&, HandShakeBase&);
|
||||
output_buffer& operator<<(output_buffer&, const HandShakeBase&);
|
||||
|
||||
|
||||
// Message Factory definition
|
||||
// uses the ContentType enumeration for unique id
|
||||
typedef Factory<Message> MessageFactory;
|
||||
void InitMessageFactory(MessageFactory&); // registers derived classes
|
||||
|
||||
// HandShake Factory definition
|
||||
// uses the HandShakeType enumeration for unique id
|
||||
typedef Factory<HandShakeBase> HandShakeFactory;
|
||||
void InitHandShakeFactory(HandShakeFactory&); // registers derived classes
|
||||
|
||||
// ServerKey Factory definition
|
||||
// uses KeyExchangeAlgorithm enumeration for unique id
|
||||
typedef Factory<ServerKeyBase> ServerKeyFactory;
|
||||
void InitServerKeyFactory(ServerKeyFactory&);
|
||||
|
||||
// ClientKey Factory definition
|
||||
// uses KeyExchangeAlgorithm enumeration for unique id
|
||||
typedef Factory<ClientKeyBase> ClientKeyFactory;
|
||||
void InitClientKeyFactory(ClientKeyFactory&);
|
||||
|
||||
|
||||
// Message Creators
|
||||
Message* CreateHandShake();
|
||||
Message* CreateCipherSpec();
|
||||
Message* CreateAlert();
|
||||
Message* CreateData();
|
||||
|
||||
|
||||
// HandShake Creators
|
||||
HandShakeBase* CreateCertificate();
|
||||
HandShakeBase* CreateHelloRequest();
|
||||
HandShakeBase* CreateClientHello();
|
||||
HandShakeBase* CreateServerHello();
|
||||
HandShakeBase* CreateServerKeyExchange();
|
||||
HandShakeBase* CreateCertificateRequest();
|
||||
HandShakeBase* CreateServerHelloDone();
|
||||
HandShakeBase* CreateClientKeyExchange();
|
||||
HandShakeBase* CreateCertificateVerify();
|
||||
HandShakeBase* CreateFinished();
|
||||
|
||||
|
||||
// ServerKey Exchange Creators
|
||||
ServerKeyBase* CreateRSAServerKEA();
|
||||
ServerKeyBase* CreateDHServerKEA();
|
||||
ServerKeyBase* CreateFortezzaServerKEA();
|
||||
|
||||
// ClientKey Exchange Creators
|
||||
ClientKeyBase* CreateRSAClient();
|
||||
ClientKeyBase* CreateDHClient();
|
||||
ClientKeyBase* CreateFortezzaClient();
|
||||
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_IMP_HPP
|
||||
+693
@@ -0,0 +1,693 @@
|
||||
/*
|
||||
Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL internal header defines SSL supporting types not specified in the
|
||||
* draft along with type conversion functions and openssl compatibility
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_INT_HPP
|
||||
#define yaSSL_INT_HPP
|
||||
|
||||
#include "yassl_imp.hpp"
|
||||
#include "yassl_error.hpp"
|
||||
#include "crypto_wrapper.hpp"
|
||||
#include "cert_wrapper.hpp"
|
||||
#include "log.hpp"
|
||||
#include "lock.hpp"
|
||||
#include "openssl/ssl.h" // ASN1_STRING and DH
|
||||
|
||||
// Check if _POSIX_THREADS should be forced
|
||||
#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux))
|
||||
// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
|
||||
// Netware supports pthreads but does not announce it
|
||||
#define _POSIX_THREADS
|
||||
#endif
|
||||
|
||||
#ifdef _POSIX_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
// State Machine for Record Layer Protocol
|
||||
enum RecordLayerState {
|
||||
recordNotReady = 0, // fatal error, no more processing
|
||||
recordReady
|
||||
};
|
||||
|
||||
|
||||
// State Machine for HandShake Protocol
|
||||
enum HandShakeState {
|
||||
handShakeNotReady = 0, // fatal error, no more processing
|
||||
preHandshake, // initial state
|
||||
inHandshake, // handshake started
|
||||
handShakeReady // handshake done
|
||||
};
|
||||
|
||||
|
||||
// client input HandShake state, use if HandShakeState == inHandShake
|
||||
enum ClientState {
|
||||
serverNull = 0,
|
||||
serverHelloComplete,
|
||||
serverCertComplete,
|
||||
serverKeyExchangeComplete,
|
||||
serverHelloDoneComplete,
|
||||
serverFinishedComplete
|
||||
};
|
||||
|
||||
|
||||
// server input HandShake state, use if HandShakeState == inHandShake
|
||||
enum ServerState {
|
||||
clientNull = 0,
|
||||
clientHelloComplete,
|
||||
clientKeyExchangeComplete,
|
||||
clientFinishedComplete
|
||||
};
|
||||
|
||||
|
||||
// client connect state for nonblocking restart
|
||||
enum ConnectState {
|
||||
CONNECT_BEGIN = 0,
|
||||
CLIENT_HELLO_SENT,
|
||||
FIRST_REPLY_DONE,
|
||||
FINISHED_DONE,
|
||||
SECOND_REPLY_DONE
|
||||
};
|
||||
|
||||
|
||||
// server accpet state for nonblocking restart
|
||||
enum AcceptState {
|
||||
ACCEPT_BEGIN = 0,
|
||||
ACCEPT_FIRST_REPLY_DONE,
|
||||
SERVER_HELLO_DONE,
|
||||
ACCEPT_SECOND_REPLY_DONE,
|
||||
ACCEPT_FINISHED_DONE,
|
||||
ACCEPT_THIRD_REPLY_DONE
|
||||
};
|
||||
|
||||
|
||||
// combines all states
|
||||
class States {
|
||||
RecordLayerState recordLayer_;
|
||||
HandShakeState handshakeLayer_;
|
||||
ClientState clientState_;
|
||||
ServerState serverState_;
|
||||
ConnectState connectState_;
|
||||
AcceptState acceptState_;
|
||||
char errorString_[MAX_ERROR_SZ];
|
||||
YasslError what_;
|
||||
public:
|
||||
States();
|
||||
|
||||
const RecordLayerState& getRecord() const;
|
||||
const HandShakeState& getHandShake() const;
|
||||
const ClientState& getClient() const;
|
||||
const ServerState& getServer() const;
|
||||
const ConnectState& GetConnect() const;
|
||||
const AcceptState& GetAccept() const;
|
||||
const char* getString() const;
|
||||
YasslError What() const;
|
||||
|
||||
RecordLayerState& useRecord();
|
||||
HandShakeState& useHandShake();
|
||||
ClientState& useClient();
|
||||
ServerState& useServer();
|
||||
ConnectState& UseConnect();
|
||||
AcceptState& UseAccept();
|
||||
char* useString();
|
||||
void SetError(YasslError);
|
||||
private:
|
||||
States(const States&); // hide copy
|
||||
States& operator=(const States&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// holds all factories
|
||||
class sslFactory {
|
||||
MessageFactory messageFactory_; // creates new messages by type
|
||||
HandShakeFactory handShakeFactory_; // creates new handshake types
|
||||
ServerKeyFactory serverKeyFactory_; // creates new server key types
|
||||
ClientKeyFactory clientKeyFactory_; // creates new client key types
|
||||
|
||||
sslFactory(); // only GetSSL_Factory creates
|
||||
public:
|
||||
const MessageFactory& getMessage() const;
|
||||
const HandShakeFactory& getHandShake() const;
|
||||
const ServerKeyFactory& getServerKey() const;
|
||||
const ClientKeyFactory& getClientKey() const;
|
||||
|
||||
friend sslFactory& GetSSL_Factory(); // singleton creator
|
||||
private:
|
||||
sslFactory(const sslFactory&); // hide copy
|
||||
sslFactory& operator=(const sslFactory&); // and assign
|
||||
};
|
||||
|
||||
|
||||
#undef X509_NAME // wincrypt.h clash
|
||||
|
||||
// openSSL X509 names
|
||||
class X509_NAME {
|
||||
char* name_;
|
||||
size_t sz_;
|
||||
ASN1_STRING entry_;
|
||||
public:
|
||||
X509_NAME(const char*, size_t sz);
|
||||
~X509_NAME();
|
||||
|
||||
const char* GetName() const;
|
||||
ASN1_STRING* GetEntry(int i);
|
||||
size_t GetLength() const;
|
||||
private:
|
||||
X509_NAME(const X509_NAME&); // hide copy
|
||||
X509_NAME& operator=(const X509_NAME&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class StringHolder {
|
||||
ASN1_STRING asnString_;
|
||||
public:
|
||||
StringHolder(const char* str, int sz);
|
||||
~StringHolder();
|
||||
|
||||
ASN1_STRING* GetString();
|
||||
private:
|
||||
StringHolder(const StringHolder&); // hide copy
|
||||
StringHolder& operator=(const StringHolder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// openSSL X509
|
||||
class X509 {
|
||||
X509_NAME issuer_;
|
||||
X509_NAME subject_;
|
||||
StringHolder beforeDate_; // not valid before
|
||||
StringHolder afterDate_; // not valid after
|
||||
public:
|
||||
X509(const char* i, size_t, const char* s, size_t,
|
||||
const char* b, int, const char* a, int);
|
||||
~X509() {}
|
||||
|
||||
X509_NAME* GetIssuer();
|
||||
X509_NAME* GetSubject();
|
||||
|
||||
ASN1_STRING* GetBefore();
|
||||
ASN1_STRING* GetAfter();
|
||||
|
||||
private:
|
||||
X509(const X509&); // hide copy
|
||||
X509& operator=(const X509&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// openSSL bignum
|
||||
struct BIGNUM {
|
||||
/*
|
||||
gcc 2.96 fix: because of two Integer classes (yaSSL::Integer and
|
||||
TaoCrypt::Integer), we need to explicitly state the namespace
|
||||
here to let gcc 2.96 deduce the correct type.
|
||||
*/
|
||||
yaSSL::Integer int_;
|
||||
void assign(const byte* b, uint s) { int_.assign(b,s); }
|
||||
};
|
||||
|
||||
|
||||
// openSSL session
|
||||
class SSL_SESSION {
|
||||
opaque sessionID_[ID_LEN];
|
||||
opaque master_secret_[SECRET_LEN];
|
||||
Cipher suite_[SUITE_LEN];
|
||||
uint bornOn_; // create time in seconds
|
||||
uint timeout_; // timeout in seconds
|
||||
RandomPool& random_; // will clean master secret
|
||||
X509* peerX509_;
|
||||
public:
|
||||
explicit SSL_SESSION(RandomPool&);
|
||||
SSL_SESSION(const SSL&, RandomPool&);
|
||||
~SSL_SESSION();
|
||||
|
||||
const opaque* GetID() const;
|
||||
const opaque* GetSecret() const;
|
||||
const Cipher* GetSuite() const;
|
||||
uint GetBornOn() const;
|
||||
uint GetTimeOut() const;
|
||||
X509* GetPeerX509() const;
|
||||
void SetTimeOut(uint);
|
||||
|
||||
SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
|
||||
private:
|
||||
SSL_SESSION(const SSL_SESSION&); // hide copy
|
||||
|
||||
void CopyX509(X509*);
|
||||
};
|
||||
|
||||
|
||||
// holds all sessions
|
||||
class Sessions {
|
||||
STL::list<SSL_SESSION*> list_;
|
||||
RandomPool random_; // for session cleaning
|
||||
Mutex mutex_; // no-op for single threaded
|
||||
int count_; // flush counter
|
||||
|
||||
Sessions() : count_(0) {} // only GetSessions can create
|
||||
public:
|
||||
SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0);
|
||||
void add(const SSL&);
|
||||
void remove(const opaque*);
|
||||
void Flush();
|
||||
|
||||
~Sessions();
|
||||
|
||||
friend Sessions& GetSessions(); // singleton creator
|
||||
private:
|
||||
Sessions(const Sessions&); // hide copy
|
||||
Sessions& operator=(const Sessions&); // and assign
|
||||
};
|
||||
|
||||
|
||||
#ifdef _POSIX_THREADS
|
||||
typedef pthread_t THREAD_ID_T;
|
||||
#else
|
||||
typedef DWORD THREAD_ID_T;
|
||||
#endif
|
||||
|
||||
// thread error data
|
||||
struct ThreadError {
|
||||
THREAD_ID_T threadID_;
|
||||
int errorID_;
|
||||
};
|
||||
|
||||
|
||||
// holds all errors
|
||||
class Errors {
|
||||
STL::list<ThreadError> list_;
|
||||
Mutex mutex_;
|
||||
|
||||
Errors() {} // only GetErrors can create
|
||||
public:
|
||||
int Lookup(bool peek); // self lookup
|
||||
void Add(int);
|
||||
void Remove(); // remove self
|
||||
|
||||
~Errors() {}
|
||||
|
||||
friend Errors& GetErrors(); // singleton creator
|
||||
private:
|
||||
Errors(const Errors&); // hide copy
|
||||
Errors& operator=(const Errors); // and assign
|
||||
};
|
||||
|
||||
|
||||
Sessions& GetSessions(); // forward singletons
|
||||
sslFactory& GetSSL_Factory();
|
||||
Errors& GetErrors();
|
||||
|
||||
|
||||
// openSSL method and context types
|
||||
class SSL_METHOD {
|
||||
ProtocolVersion version_;
|
||||
ConnectionEnd side_;
|
||||
bool verifyPeer_; // request or send certificate
|
||||
bool verifyNone_; // whether to verify certificate
|
||||
bool failNoCert_;
|
||||
bool multipleProtocol_; // for SSLv23 compatibility
|
||||
public:
|
||||
SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv,
|
||||
bool multipleProtocol = false);
|
||||
|
||||
ProtocolVersion getVersion() const;
|
||||
ConnectionEnd getSide() const;
|
||||
|
||||
void setVerifyPeer();
|
||||
void setVerifyNone();
|
||||
void setFailNoCert();
|
||||
|
||||
bool verifyPeer() const;
|
||||
bool verifyNone() const;
|
||||
bool failNoCert() const;
|
||||
bool multipleProtocol() const;
|
||||
private:
|
||||
SSL_METHOD(const SSL_METHOD&); // hide copy
|
||||
SSL_METHOD& operator=(const SSL_METHOD&); // and assign
|
||||
};
|
||||
|
||||
|
||||
struct Ciphers {
|
||||
bool setSuites_; // user set suites from default
|
||||
byte suites_[MAX_SUITE_SZ]; // new suites
|
||||
int suiteSz_; // suite length in bytes
|
||||
|
||||
Ciphers() : setSuites_(false), suiteSz_(0) {}
|
||||
};
|
||||
|
||||
|
||||
struct DH; // forward
|
||||
|
||||
|
||||
// save for SSL construction
|
||||
struct DH_Parms {
|
||||
Integer p_;
|
||||
Integer g_;
|
||||
bool set_; // if set by user
|
||||
|
||||
DH_Parms() : set_(false) {}
|
||||
};
|
||||
|
||||
|
||||
enum StatsField {
|
||||
Accept, Connect, AcceptGood, ConnectGood, AcceptRenegotiate,
|
||||
ConnectRenegotiate, Hits, CbHits, CacheFull, Misses, Timeouts, Number,
|
||||
GetCacheSize, VerifyMode, VerifyDepth
|
||||
};
|
||||
|
||||
|
||||
// SSL stats
|
||||
struct Stats {
|
||||
long accept_;
|
||||
long connect_;
|
||||
long acceptGood_;
|
||||
long connectGood_;
|
||||
long acceptRenegotiate_;
|
||||
long connectRenegotiate_;
|
||||
|
||||
long hits_;
|
||||
long cbHits_;
|
||||
long cacheFull_;
|
||||
long misses_;
|
||||
long timeouts_;
|
||||
long number_;
|
||||
long getCacheSize_;
|
||||
|
||||
int verifyMode_;
|
||||
int verifyDepth_;
|
||||
public:
|
||||
Stats() : accept_(0), connect_(0), acceptGood_(0), connectGood_(0),
|
||||
acceptRenegotiate_(0), connectRenegotiate_(0), hits_(0), cbHits_(0),
|
||||
cacheFull_(0), misses_(0), timeouts_(0), number_(0), getCacheSize_(0),
|
||||
verifyMode_(0), verifyDepth_(0)
|
||||
{}
|
||||
private:
|
||||
Stats(const Stats&); // hide copy
|
||||
Stats& operator=(const Stats&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// the SSL context
|
||||
class SSL_CTX {
|
||||
public:
|
||||
typedef STL::list<x509*> CertList;
|
||||
private:
|
||||
SSL_METHOD* method_;
|
||||
x509* certificate_;
|
||||
x509* privateKey_;
|
||||
CertList caList_;
|
||||
Ciphers ciphers_;
|
||||
DH_Parms dhParms_;
|
||||
pem_password_cb passwordCb_;
|
||||
void* userData_;
|
||||
bool sessionCacheOff_;
|
||||
bool sessionCacheFlushOff_;
|
||||
Stats stats_;
|
||||
Mutex mutex_; // for Stats
|
||||
VerifyCallback verifyCallback_;
|
||||
public:
|
||||
explicit SSL_CTX(SSL_METHOD* meth);
|
||||
~SSL_CTX();
|
||||
|
||||
const x509* getCert() const;
|
||||
const x509* getKey() const;
|
||||
const SSL_METHOD* getMethod() const;
|
||||
const Ciphers& GetCiphers() const;
|
||||
const DH_Parms& GetDH_Parms() const;
|
||||
const Stats& GetStats() const;
|
||||
const VerifyCallback getVerifyCallback() const;
|
||||
pem_password_cb GetPasswordCb() const;
|
||||
void* GetUserData() const;
|
||||
bool GetSessionCacheOff() const;
|
||||
bool GetSessionCacheFlushOff() const;
|
||||
|
||||
void setVerifyPeer();
|
||||
void setVerifyNone();
|
||||
void setFailNoCert();
|
||||
void setVerifyCallback(VerifyCallback);
|
||||
bool SetCipherList(const char*);
|
||||
bool SetDH(const DH&);
|
||||
void SetPasswordCb(pem_password_cb cb);
|
||||
void SetUserData(void*);
|
||||
void SetSessionCacheOff();
|
||||
void SetSessionCacheFlushOff();
|
||||
|
||||
void IncrementStats(StatsField);
|
||||
void AddCA(x509* ca);
|
||||
const CertList& GetCA_List() const;
|
||||
|
||||
friend int read_file(SSL_CTX*, const char*, int, CertType);
|
||||
private:
|
||||
SSL_CTX(const SSL_CTX&); // hide copy
|
||||
SSL_CTX& operator=(const SSL_CTX&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// holds all cryptographic types
|
||||
class Crypto {
|
||||
Digest* digest_; // agreed upon digest
|
||||
BulkCipher* cipher_; // agreed upon cipher
|
||||
DiffieHellman* dh_; // dh parms
|
||||
RandomPool random_; // random number generator
|
||||
CertManager cert_; // manages certificates
|
||||
public:
|
||||
explicit Crypto();
|
||||
~Crypto();
|
||||
|
||||
const Digest& get_digest() const;
|
||||
const BulkCipher& get_cipher() const;
|
||||
const DiffieHellman& get_dh() const;
|
||||
const RandomPool& get_random() const;
|
||||
const CertManager& get_certManager() const;
|
||||
|
||||
Digest& use_digest();
|
||||
BulkCipher& use_cipher();
|
||||
DiffieHellman& use_dh();
|
||||
RandomPool& use_random();
|
||||
CertManager& use_certManager();
|
||||
|
||||
void SetDH(DiffieHellman*);
|
||||
void SetDH(const DH_Parms&);
|
||||
void setDigest(Digest*);
|
||||
void setCipher(BulkCipher*);
|
||||
|
||||
bool DhSet();
|
||||
private:
|
||||
Crypto(const Crypto&); // hide copy
|
||||
Crypto& operator=(const Crypto&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// holds all handshake and verify hashes
|
||||
class sslHashes {
|
||||
MD5 md5HandShake_; // md5 handshake hash
|
||||
SHA shaHandShake_; // sha handshake hash
|
||||
Finished verify_; // peer's verify hash
|
||||
Hashes certVerify_; // peer's cert verify hash
|
||||
public:
|
||||
sslHashes() {}
|
||||
|
||||
const MD5& get_MD5() const;
|
||||
const SHA& get_SHA() const;
|
||||
const Finished& get_verify() const;
|
||||
const Hashes& get_certVerify() const;
|
||||
|
||||
MD5& use_MD5();
|
||||
SHA& use_SHA();
|
||||
Finished& use_verify();
|
||||
Hashes& use_certVerify();
|
||||
private:
|
||||
sslHashes(const sslHashes&); // hide copy
|
||||
sslHashes& operator=(const sslHashes&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// holds input and output buffers
|
||||
class Buffers {
|
||||
public:
|
||||
typedef STL::list<input_buffer*> inputList;
|
||||
typedef STL::list<output_buffer*> outputList;
|
||||
private:
|
||||
inputList dataList_; // list of users app data / handshake
|
||||
outputList handShakeList_; // buffered handshake msgs
|
||||
input_buffer* rawInput_; // buffered raw input yet to process
|
||||
public:
|
||||
Buffers();
|
||||
~Buffers();
|
||||
|
||||
const inputList& getData() const;
|
||||
const outputList& getHandShake() const;
|
||||
|
||||
inputList& useData();
|
||||
outputList& useHandShake();
|
||||
|
||||
void SetRawInput(input_buffer*); // takes ownership
|
||||
input_buffer* TakeRawInput(); // takes ownership
|
||||
private:
|
||||
Buffers(const Buffers&); // hide copy
|
||||
Buffers& operator=(const Buffers&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// wraps security parameters
|
||||
class Security {
|
||||
Connection conn_; // connection information
|
||||
Parameters parms_; // may be pending
|
||||
SSL_SESSION resumeSession_; // if resuming
|
||||
SSL_CTX* ctx_; // context used to init
|
||||
bool resuming_; // trying to resume
|
||||
public:
|
||||
Security(ProtocolVersion, RandomPool&, ConnectionEnd, const Ciphers&,
|
||||
SSL_CTX*, bool);
|
||||
|
||||
const SSL_CTX* GetContext() const;
|
||||
const Connection& get_connection() const;
|
||||
const Parameters& get_parms() const;
|
||||
const SSL_SESSION& get_resume() const;
|
||||
bool get_resuming() const;
|
||||
|
||||
Connection& use_connection();
|
||||
Parameters& use_parms();
|
||||
SSL_SESSION& use_resume();
|
||||
|
||||
void set_resuming(bool b);
|
||||
private:
|
||||
Security(const Security&); // hide copy
|
||||
Security& operator=(const Security&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// THE SSL type
|
||||
class SSL {
|
||||
Crypto crypto_; // agreed crypto agents
|
||||
Security secure_; // Connection and Session parms
|
||||
States states_; // Record and HandShake states
|
||||
sslHashes hashes_; // handshake, finished hashes
|
||||
Socket socket_; // socket wrapper
|
||||
Buffers buffers_; // buffered handshakes and data
|
||||
Log log_; // logger
|
||||
bool quietShutdown_;
|
||||
|
||||
// optimization variables
|
||||
bool has_data_; // buffered data ready?
|
||||
public:
|
||||
SSL(SSL_CTX* ctx);
|
||||
|
||||
// gets and uses
|
||||
const Crypto& getCrypto() const;
|
||||
const Security& getSecurity() const;
|
||||
const States& getStates() const;
|
||||
const sslHashes& getHashes() const;
|
||||
const sslFactory& getFactory() const;
|
||||
const Socket& getSocket() const;
|
||||
YasslError GetError() const;
|
||||
bool GetMultiProtocol() const;
|
||||
bool CompressionOn() const;
|
||||
|
||||
Crypto& useCrypto();
|
||||
Security& useSecurity();
|
||||
States& useStates();
|
||||
sslHashes& useHashes();
|
||||
Socket& useSocket();
|
||||
Log& useLog();
|
||||
Buffers& useBuffers();
|
||||
|
||||
bool HasData() const;
|
||||
bool GetQuietShutdown() const;
|
||||
|
||||
// sets
|
||||
void set_pending(Cipher suite);
|
||||
void set_random(const opaque*, ConnectionEnd);
|
||||
void set_sessionID(const opaque*);
|
||||
void set_session(SSL_SESSION*);
|
||||
void set_preMaster(const opaque*, uint);
|
||||
void set_masterSecret(const opaque*);
|
||||
void SetError(YasslError);
|
||||
int SetCompression();
|
||||
void UnSetCompression();
|
||||
void SetQuietShutdown(bool mode);
|
||||
|
||||
// helpers
|
||||
bool isTLS() const;
|
||||
bool isTLSv1_1() const;
|
||||
void order_error();
|
||||
void makeMasterSecret();
|
||||
void makeTLSMasterSecret();
|
||||
void addData(input_buffer* data);
|
||||
void fillData(Data&);
|
||||
void PeekData(Data&);
|
||||
void addBuffer(output_buffer* b);
|
||||
void flushBuffer();
|
||||
void verifyState(const RecordLayerHeader&);
|
||||
void verifyState(const HandShakeHeader&);
|
||||
void verifyState(ClientState);
|
||||
void verifyState(ServerState);
|
||||
void verfiyHandShakeComplete();
|
||||
void matchSuite(const opaque*, uint length);
|
||||
void deriveKeys();
|
||||
void deriveTLSKeys();
|
||||
void Send(const byte*, uint);
|
||||
|
||||
uint bufferedData();
|
||||
uint get_SEQIncrement(bool);
|
||||
|
||||
const byte* get_macSecret(bool);
|
||||
private:
|
||||
void storeKeys(const opaque*);
|
||||
void setKeys();
|
||||
void verifyClientState(HandShakeType);
|
||||
void verifyServerState(HandShakeType);
|
||||
|
||||
SSL(const SSL&); // hide copy
|
||||
const SSL& operator=(const SSL&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// compression
|
||||
int Compress(const byte*, int, input_buffer&);
|
||||
int DeCompress(input_buffer&, int, input_buffer&);
|
||||
|
||||
|
||||
// conversion functions
|
||||
void c32to24(uint32, uint24&);
|
||||
void c24to32(const uint24, uint32&);
|
||||
|
||||
uint32 c24to32(const uint24);
|
||||
|
||||
void ato16(const opaque*, uint16&);
|
||||
void ato24(const opaque*, uint24&);
|
||||
|
||||
void c16toa(uint16, opaque*);
|
||||
void c24toa(const uint24, opaque*);
|
||||
void c32toa(uint32 u32, opaque*);
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // yaSSL_INT_HPP
|
||||
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* yaSSL types header defines all constants, enums, and typedefs
|
||||
* from the SSL.v3 specification "draft-freier-ssl-version3-02.txt"
|
||||
*/
|
||||
|
||||
|
||||
#ifndef yaSSL_TYPES_HPP
|
||||
#define yaSSL_TYPES_HPP
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include "type_traits.hpp"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// disable conversion warning
|
||||
// 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
|
||||
#pragma warning(disable:4244 4996)
|
||||
#endif
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
#define YASSL_LIB
|
||||
|
||||
|
||||
#ifdef YASSL_PURE_C
|
||||
|
||||
// library allocation
|
||||
struct new_t {}; // yaSSL New type
|
||||
extern new_t ys; // pass in parameter
|
||||
|
||||
} // namespace yaSSL
|
||||
|
||||
void* operator new (size_t, yaSSL::new_t);
|
||||
void* operator new[](size_t, yaSSL::new_t);
|
||||
|
||||
void operator delete (void*, yaSSL::new_t);
|
||||
void operator delete[](void*, yaSSL::new_t);
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
template<typename T>
|
||||
void ysDelete(T* ptr)
|
||||
{
|
||||
if (ptr) ptr->~T();
|
||||
::operator delete(ptr, yaSSL::ys);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ysArrayDelete(T* ptr)
|
||||
{
|
||||
// can't do array placement destruction since not tracking size in
|
||||
// allocation, only allow builtins to use array placement since they
|
||||
// don't need destructors called
|
||||
typedef char builtin[TaoCrypt::IsFundamentalType<T>::Yes ? 1 : -1];
|
||||
(void)sizeof(builtin);
|
||||
|
||||
::operator delete[](ptr, yaSSL::ys);
|
||||
}
|
||||
|
||||
#define NEW_YS new (yaSSL::ys)
|
||||
|
||||
// to resolve compiler generated operator delete on base classes with
|
||||
// virtual destructors (when on stack), make sure doesn't get called
|
||||
class virtual_base {
|
||||
public:
|
||||
static void operator delete(void*) { assert(0); }
|
||||
};
|
||||
|
||||
|
||||
#else // YASSL_PURE_C
|
||||
|
||||
|
||||
template<typename T>
|
||||
void ysDelete(T* ptr)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ysArrayDelete(T* ptr)
|
||||
{
|
||||
delete[] ptr;
|
||||
}
|
||||
|
||||
#define NEW_YS new
|
||||
|
||||
class virtual_base {};
|
||||
|
||||
|
||||
|
||||
#endif // YASSL_PURE_C
|
||||
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef uint8 uint24[3];
|
||||
typedef uint32 uint64[2];
|
||||
|
||||
typedef uint8 opaque;
|
||||
typedef opaque byte;
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
|
||||
#ifdef USE_SYS_STL
|
||||
// use system STL
|
||||
#define STL_VECTOR_FILE <vector>
|
||||
#define STL_LIST_FILE <list>
|
||||
#define STL_ALGORITHM_FILE <algorithm>
|
||||
#define STL_MEMORY_FILE <memory>
|
||||
#define STL_PAIR_FILE <utility>
|
||||
|
||||
#define STL_NAMESPACE std
|
||||
#else
|
||||
// use mySTL
|
||||
#define STL_VECTOR_FILE "vector.hpp"
|
||||
#define STL_LIST_FILE "list.hpp"
|
||||
#define STL_ALGORITHM_FILE "algorithm.hpp"
|
||||
#define STL_MEMORY_FILE "memory.hpp"
|
||||
#define STL_PAIR_FILE "pair.hpp"
|
||||
|
||||
#define STL_NAMESPACE mySTL
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef min
|
||||
template <typename T>
|
||||
T min(T a, T b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// all length constants in bytes
|
||||
const int ID_LEN = 32; // session id length
|
||||
const int SUITE_LEN = 2; // cipher suite length
|
||||
const int SECRET_LEN = 48; // pre RSA and all master secret length
|
||||
const int MASTER_ROUNDS = 3; // master secret derivation rounds
|
||||
const int RAN_LEN = 32; // client and server random length
|
||||
const int MAC_BLOCK_SZ = 64; // MAC block size, & padding
|
||||
const int MD5_LEN = 16; // MD5 digest length
|
||||
const int SHA_LEN = 20; // SHA digest length
|
||||
const int RMD_LEN = 20; // RIPEMD-160 digest length
|
||||
const int PREFIX = 3; // up to 3 prefix letters for secret rounds
|
||||
const int KEY_PREFIX = 7; // up to 7 prefix letters for key rounds
|
||||
const int FORTEZZA_MAX = 128; // Maximum Fortezza Key length
|
||||
const int MAX_SUITE_SZ = 128; // 64 max suites * sizeof(suite)
|
||||
const int MAX_SUITE_NAME = 48; // max length of suite name
|
||||
const int MAX_CIPHERS = 32; // max supported ciphers for cipher list
|
||||
const int SIZEOF_ENUM = 1; // SSL considers an enum 1 byte, not 4
|
||||
const int SIZEOF_SENDER = 4; // Sender constant, for finished generation
|
||||
const int PAD_MD5 = 48; // pad length 1 and 2 for md5 finished
|
||||
const int PAD_SHA = 40; // should be 44, specd wrong by netscape
|
||||
const int PAD_RMD = 44; // pad length for RIPEMD-160, some use 40??
|
||||
const int CERT_HEADER = 3; // always use 3 bytes for certificate
|
||||
const int CERT_TYPES = 7; // certificate request types
|
||||
const int REQUEST_HEADER = 2; // request uses 2 bytes
|
||||
const int VERIFY_HEADER = 2; // verify length field
|
||||
const int MIN_CERT_TYPES = 1; // minimum certificate request types
|
||||
const int MIN_DIS_NAMES = 3; // minimum distinguished names
|
||||
const int MIN_DIS_SIZE = 1; // minimum distinguished name size
|
||||
const int RECORD_HEADER = 5; // type + version + length(2)
|
||||
const int HANDSHAKE_HEADER = 4; // type + length(3)
|
||||
const int FINISHED_SZ = MD5_LEN + SHA_LEN; // sizeof finished data
|
||||
const int TLS_FINISHED_SZ = 12; // TLS verify data size
|
||||
const int SEQ_SZ = 8; // 64 bit sequence number
|
||||
const int LENGTH_SZ = 2; // length field for HMAC, data only
|
||||
const int VERSION_SZ = SIZEOF_ENUM * 2; // SSL/TLS length of version
|
||||
const int DES_KEY_SZ = 8; // DES Key length
|
||||
const int DES_EDE_KEY_SZ = 24; // DES EDE Key length
|
||||
const int DES_BLOCK = 8; // DES is always fixed block size 8
|
||||
const int DES_IV_SZ = DES_BLOCK; // Init Vector length for DES
|
||||
const int RC4_KEY_SZ = 16; // RC4 Key length
|
||||
const int AES_128_KEY_SZ = 16; // AES 128bit Key length
|
||||
const int AES_192_KEY_SZ = 24; // AES 192bit Key length
|
||||
const int AES_256_KEY_SZ = 32; // AES 256bit Key length
|
||||
const int AES_BLOCK_SZ = 16; // AES 128bit block size, rfc 3268
|
||||
const int AES_IV_SZ = AES_BLOCK_SZ; // AES Init Vector length
|
||||
const int DSS_SIG_SZ = 40; // two 20 byte high byte first Integers
|
||||
const int DSS_ENCODED_EXTRA = 6; // seqID + len(1) + (intID + len(1)) * 2
|
||||
const int EVP_SALT_SZ = 8;
|
||||
const int MASTER_LABEL_SZ = 13; // TLS master secret label size
|
||||
const int KEY_LABEL_SZ = 13; // TLS key block expansion size
|
||||
const int FINISHED_LABEL_SZ = 15; // TLS finished lable length
|
||||
const int SEED_LEN = RAN_LEN * 2; // TLS seed, client + server random
|
||||
const int DEFAULT_TIMEOUT = 500; // Default Session timeout in seconds
|
||||
const int MAX_RECORD_SIZE = 16384; // 2^14, max size by standard
|
||||
const int COMPRESS_EXTRA = 1024; // extra compression possible addition
|
||||
const int SESSION_FLUSH_COUNT = 256; // when to flush session cache
|
||||
|
||||
|
||||
typedef uint8 Cipher; // first byte is always 0x00 for SSLv3 & TLS
|
||||
|
||||
typedef opaque Random[RAN_LEN];
|
||||
|
||||
typedef opaque* DistinguishedName;
|
||||
|
||||
typedef bool IsExportable;
|
||||
|
||||
|
||||
enum CompressionMethod { no_compression = 0, zlib = 221 };
|
||||
|
||||
enum CipherType { stream, block };
|
||||
|
||||
enum CipherChoice { change_cipher_spec_choice = 1 };
|
||||
|
||||
enum PublicValueEncoding { implicit_encoding, explicit_encoding };
|
||||
|
||||
enum ConnectionEnd { server_end, client_end };
|
||||
|
||||
enum AlertLevel { warning = 1, fatal = 2 };
|
||||
|
||||
|
||||
|
||||
// Record Layer Header identifier from page 12
|
||||
enum ContentType {
|
||||
no_type = 0,
|
||||
change_cipher_spec = 20,
|
||||
alert = 21,
|
||||
handshake = 22,
|
||||
application_data = 23
|
||||
};
|
||||
|
||||
|
||||
// HandShake Layer Header identifier from page 20
|
||||
enum HandShakeType {
|
||||
no_shake = -1,
|
||||
hello_request = 0,
|
||||
client_hello = 1,
|
||||
server_hello = 2,
|
||||
certificate = 11,
|
||||
server_key_exchange = 12,
|
||||
certificate_request = 13,
|
||||
server_hello_done = 14,
|
||||
certificate_verify = 15,
|
||||
client_key_exchange = 16,
|
||||
finished = 20
|
||||
};
|
||||
|
||||
|
||||
// Valid Alert types from page 16/17
|
||||
enum AlertDescription {
|
||||
close_notify = 0,
|
||||
unexpected_message = 10,
|
||||
bad_record_mac = 20,
|
||||
decompression_failure = 30,
|
||||
handshake_failure = 40,
|
||||
no_certificate = 41,
|
||||
bad_certificate = 42,
|
||||
unsupported_certificate = 43,
|
||||
certificate_revoked = 44,
|
||||
certificate_expired = 45,
|
||||
certificate_unknown = 46,
|
||||
illegal_parameter = 47
|
||||
};
|
||||
|
||||
|
||||
// Supported Key Exchange Protocols
|
||||
enum KeyExchangeAlgorithm {
|
||||
no_kea = 0,
|
||||
rsa_kea,
|
||||
diffie_hellman_kea,
|
||||
fortezza_kea
|
||||
};
|
||||
|
||||
|
||||
// Supported Authentication Schemes
|
||||
enum SignatureAlgorithm {
|
||||
anonymous_sa_algo = 0,
|
||||
rsa_sa_algo,
|
||||
dsa_sa_algo
|
||||
};
|
||||
|
||||
|
||||
// Valid client certificate request types from page 27
|
||||
enum ClientCertificateType {
|
||||
rsa_sign = 1,
|
||||
dss_sign = 2,
|
||||
rsa_fixed_dh = 3,
|
||||
dss_fixed_dh = 4,
|
||||
rsa_ephemeral_dh = 5,
|
||||
dss_ephemeral_dh = 6,
|
||||
fortezza_kea_cert = 20
|
||||
};
|
||||
|
||||
|
||||
// Supported Ciphers from page 43
|
||||
enum BulkCipherAlgorithm {
|
||||
cipher_null,
|
||||
rc4,
|
||||
rc2,
|
||||
des,
|
||||
triple_des, // leading 3 (3des) not valid identifier
|
||||
des40,
|
||||
idea,
|
||||
aes
|
||||
};
|
||||
|
||||
|
||||
// Supported Message Authentication Codes from page 43
|
||||
enum MACAlgorithm {
|
||||
no_mac,
|
||||
md5,
|
||||
sha,
|
||||
rmd
|
||||
};
|
||||
|
||||
|
||||
// Certificate file Type
|
||||
enum CertType { Cert = 0, PrivateKey, CA };
|
||||
|
||||
|
||||
// all Cipher Suites from pages 41/42
|
||||
const Cipher SSL_NULL_WITH_NULL_NULL = 0; // { 0x00, 0x00 }
|
||||
const Cipher SSL_RSA_WITH_NULL_MD5 = 1; // { 0x00, 0x01 }
|
||||
const Cipher SSL_RSA_WITH_NULL_SHA = 2; // { 0x00, 0x02 }
|
||||
const Cipher SSL_RSA_EXPORT_WITH_RC4_40_MD5 = 3; // { 0x00, 0x03 }
|
||||
const Cipher SSL_RSA_WITH_RC4_128_MD5 = 4; // { 0x00, 0x04 }
|
||||
const Cipher SSL_RSA_WITH_RC4_128_SHA = 5; // { 0x00, 0x05 }
|
||||
const Cipher SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 6; // { 0x00, 0x06 }
|
||||
const Cipher SSL_RSA_WITH_IDEA_CBC_SHA = 7; // { 0x00, 0x07 }
|
||||
const Cipher SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = 8; // { 0x00, 0x08 }
|
||||
const Cipher SSL_RSA_WITH_DES_CBC_SHA = 9; // { 0x00, 0x09 }
|
||||
const Cipher SSL_RSA_WITH_3DES_EDE_CBC_SHA = 10; // { 0x00, 0x0A }
|
||||
const Cipher SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 11; // { 0x00, 0x0B }
|
||||
const Cipher SSL_DH_DSS_WITH_DES_CBC_SHA = 12; // { 0x00, 0x0C }
|
||||
const Cipher SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = 13; // { 0x00, 0x0D }
|
||||
const Cipher SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 14; // { 0x00, 0x0E }
|
||||
const Cipher SSL_DH_RSA_WITH_DES_CBC_SHA = 15; // { 0x00, 0x0F }
|
||||
const Cipher SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = 16; // { 0x00, 0x10 }
|
||||
const Cipher SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 17; // { 0x00, 0x11 }
|
||||
const Cipher SSL_DHE_DSS_WITH_DES_CBC_SHA = 18; // { 0x00, 0x12 }
|
||||
const Cipher SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 19; // { 0x00, 0x13 }
|
||||
const Cipher SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 20; // { 0x00, 0x14 }
|
||||
const Cipher SSL_DHE_RSA_WITH_DES_CBC_SHA = 21; // { 0x00, 0x15 }
|
||||
const Cipher SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 22; // { 0x00, 0x16 }
|
||||
const Cipher SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = 23; // { 0x00, 0x17 }
|
||||
const Cipher SSL_DH_anon_WITH_RC4_128_MD5 = 24; // { 0x00, 0x18 }
|
||||
const Cipher SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 25; // { 0x00, 0x19 }
|
||||
const Cipher SSL_DH_anon_WITH_DES_CBC_SHA = 26; // { 0x00, 0x1A }
|
||||
const Cipher SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = 27; // { 0x00, 0x1B }
|
||||
const Cipher SSL_FORTEZZA_KEA_WITH_NULL_SHA = 28; // { 0x00, 0x1C }
|
||||
const Cipher SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA = 29; // { 0x00, 0x1D }
|
||||
const Cipher SSL_FORTEZZA_KEA_WITH_RC4_128_SHA = 30; // { 0x00, 0x1E }
|
||||
|
||||
// .. to 0x2B uses Kerberos Authentication
|
||||
|
||||
|
||||
// TLS AES extensions
|
||||
const Cipher TLS_RSA_WITH_AES_128_CBC_SHA = 47; // { 0x00, 0x2F }
|
||||
const Cipher TLS_DH_DSS_WITH_AES_128_CBC_SHA = 48; // { 0x00, 0x30 }
|
||||
const Cipher TLS_DH_RSA_WITH_AES_128_CBC_SHA = 49; // { 0x00, 0x31 }
|
||||
const Cipher TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 50; // { 0x00, 0x32 }
|
||||
const Cipher TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 51; // { 0x00, 0x33 }
|
||||
const Cipher TLS_DH_anon_WITH_AES_128_CBC_SHA = 52; // { 0x00, 0x34 }
|
||||
|
||||
const Cipher TLS_RSA_WITH_AES_256_CBC_SHA = 53; // { 0x00, 0x35 }
|
||||
const Cipher TLS_DH_DSS_WITH_AES_256_CBC_SHA = 54; // { 0x00, 0x36 }
|
||||
const Cipher TLS_DH_RSA_WITH_AES_256_CBC_SHA = 55; // { 0x00, 0x37 }
|
||||
const Cipher TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 56; // { 0x00, 0x38 }
|
||||
const Cipher TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 57; // { 0x00, 0x39 }
|
||||
const Cipher TLS_DH_anon_WITH_AES_256_CBC_SHA = 58; // { 0x00, 0x3A }
|
||||
|
||||
|
||||
// OpenPGP extensions
|
||||
|
||||
const Cipher TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160 = 114; // { 0x00, 0x72 };
|
||||
const Cipher TLS_DHE_DSS_WITH_AES_128_CBC_RMD160 = 115; // { 0x00, 0x73 };
|
||||
const Cipher TLS_DHE_DSS_WITH_AES_256_CBC_RMD160 = 116; // { 0x00, 0x74 };
|
||||
const Cipher TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160 = 119; // { 0x00, 0x77 };
|
||||
const Cipher TLS_DHE_RSA_WITH_AES_128_CBC_RMD160 = 120; // { 0x00, 0x78 };
|
||||
const Cipher TLS_DHE_RSA_WITH_AES_256_CBC_RMD160 = 121; // { 0x00, 0x79 };
|
||||
const Cipher TLS_RSA_WITH_3DES_EDE_CBC_RMD160 = 124; // { 0x00, 0x7C };
|
||||
const Cipher TLS_RSA_WITH_AES_128_CBC_RMD160 = 125; // { 0x00, 0x7D };
|
||||
const Cipher TLS_RSA_WITH_AES_256_CBC_RMD160 = 126; // { 0x00, 0x7E };
|
||||
|
||||
|
||||
const char* const null_str = "";
|
||||
|
||||
const char* const cipher_names[128] =
|
||||
{
|
||||
null_str, // SSL_NULL_WITH_NULL_NULL = 0
|
||||
null_str, // SSL_RSA_WITH_NULL_MD5 = 1
|
||||
null_str, // SSL_RSA_WITH_NULL_SHA = 2
|
||||
null_str, // SSL_RSA_EXPORT_WITH_RC4_40_MD5 = 3
|
||||
"RC4-MD5", // SSL_RSA_WITH_RC4_128_MD5 = 4
|
||||
"RC4-SHA", // SSL_RSA_WITH_RC4_128_SHA = 5
|
||||
null_str, // SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 6
|
||||
null_str, // SSL_RSA_WITH_IDEA_CBC_SHA = 7
|
||||
null_str, // SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = 8
|
||||
"DES-CBC-SHA", // SSL_RSA_WITH_DES_CBC_SHA = 9
|
||||
"DES-CBC3-SHA", // SSL_RSA_WITH_3DES_EDE_CBC_SHA = 10
|
||||
|
||||
null_str, // SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 11
|
||||
null_str, // SSL_DH_DSS_WITH_DES_CBC_SHA = 12
|
||||
null_str, // SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = 13
|
||||
null_str, // SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 14
|
||||
null_str, // SSL_DH_RSA_WITH_DES_CBC_SHA = 15
|
||||
null_str, // SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = 16
|
||||
null_str, // SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 17
|
||||
"EDH-DSS-DES-CBC-SHA", // SSL_DHE_DSS_WITH_DES_CBC_SHA = 18
|
||||
"EDH-DSS-DES-CBC3-SHA", // SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 19
|
||||
null_str, // SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 20
|
||||
|
||||
"EDH-RSA-DES-CBC-SHA", // SSL_DHE_RSA_WITH_DES_CBC_SHA = 21
|
||||
"EDH-RSA-DES-CBC3-SHA", // SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 22
|
||||
null_str, // SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = 23
|
||||
null_str, // SSL_DH_anon_WITH_RC4_128_MD5 = 24
|
||||
null_str, // SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 25
|
||||
null_str, // SSL_DH_anon_WITH_DES_CBC_SHA = 26
|
||||
null_str, // SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = 27
|
||||
null_str, // SSL_FORTEZZA_KEA_WITH_NULL_SHA = 28
|
||||
null_str, // SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA = 29
|
||||
null_str, // SSL_FORTEZZA_KEA_WITH_RC4_128_SHA = 30
|
||||
|
||||
null_str, null_str, null_str, null_str, null_str, // 31 - 35
|
||||
null_str, null_str, null_str, null_str, null_str, // 36 - 40
|
||||
null_str, null_str, null_str, null_str, null_str, // 41 - 45
|
||||
null_str, // 46
|
||||
|
||||
// TLS AES extensions
|
||||
"AES128-SHA", // TLS_RSA_WITH_AES_128_CBC_SHA = 47
|
||||
null_str, // TLS_DH_DSS_WITH_AES_128_CBC_SHA = 48
|
||||
null_str, // TLS_DH_RSA_WITH_AES_128_CBC_SHA = 49
|
||||
"DHE-DSS-AES128-SHA", // TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 50
|
||||
"DHE-RSA-AES128-SHA", // TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 51
|
||||
null_str, // TLS_DH_anon_WITH_AES_128_CBC_SHA = 52
|
||||
|
||||
"AES256-SHA", // TLS_RSA_WITH_AES_256_CBC_SHA = 53
|
||||
null_str, // TLS_DH_DSS_WITH_AES_256_CBC_SHA = 54
|
||||
null_str, // TLS_DH_RSA_WITH_AES_256_CBC_SHA = 55
|
||||
"DHE-DSS-AES256-SHA", // TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 56
|
||||
"DHE-RSA-AES256-SHA", // TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 57
|
||||
null_str, // TLS_DH_anon_WITH_AES_256_CBC_SHA = 58
|
||||
|
||||
null_str, // 59
|
||||
null_str, // 60
|
||||
null_str, null_str, null_str, null_str, null_str, // 61 - 65
|
||||
null_str, null_str, null_str, null_str, null_str, // 66 - 70
|
||||
null_str, null_str, null_str, null_str, null_str, // 71 - 75
|
||||
null_str, null_str, null_str, null_str, null_str, // 76 - 80
|
||||
null_str, null_str, null_str, null_str, null_str, // 81 - 85
|
||||
null_str, null_str, null_str, null_str, null_str, // 86 - 90
|
||||
null_str, null_str, null_str, null_str, null_str, // 91 - 95
|
||||
null_str, null_str, null_str, null_str, null_str, // 96 - 100
|
||||
null_str, null_str, null_str, null_str, null_str, // 101 - 105
|
||||
null_str, null_str, null_str, null_str, null_str, // 106 - 110
|
||||
null_str, null_str, null_str, // 111 - 113
|
||||
|
||||
"DHE-DSS-DES-CBC3-RMD", // TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160 = 114
|
||||
"DHE-DSS-AES128-RMD", // TLS_DHE_DSS_WITH_AES_128_CBC_RMD160 = 115
|
||||
"DHE-DSS-AES256-RMD", // TLS_DHE_DSS_WITH_AES_256_CBC_RMD160 = 116
|
||||
null_str, // 117
|
||||
null_str, // 118
|
||||
"DHE-RSA-DES-CBC3-RMD", // TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160 = 119
|
||||
"DHE-RSA-AES128-RMD", // TLS_DHE_RSA_WITH_AES_128_CBC_RMD160 = 120
|
||||
"DHE-RSA-AES256-RMD", // TLS_DHE_RSA_WITH_AES_256_CBC_RMD160 = 121
|
||||
null_str, // 122
|
||||
null_str, // 123
|
||||
"DES-CBC3-RMD", // TLS_RSA_WITH_3DES_EDE_CBC_RMD160 = 124
|
||||
"AES128-RMD", // TLS_RSA_WITH_AES_128_CBC_RMD160 = 125
|
||||
"AES256-RMD", // TLS_RSA_WITH_AES_256_CBC_RMD160 = 126
|
||||
null_str // 127
|
||||
};
|
||||
|
||||
// fill with MD5 pad size since biggest required
|
||||
const opaque PAD1[PAD_MD5] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
|
||||
};
|
||||
const opaque PAD2[PAD_MD5] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
|
||||
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
|
||||
};
|
||||
|
||||
const opaque client[SIZEOF_SENDER] = { 0x43, 0x4C, 0x4E, 0x54 };
|
||||
const opaque server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 };
|
||||
|
||||
const opaque tls_client[FINISHED_LABEL_SZ + 1] = "client finished";
|
||||
const opaque tls_server[FINISHED_LABEL_SZ + 1] = "server finished";
|
||||
|
||||
const opaque master_label[MASTER_LABEL_SZ + 1] = "master secret";
|
||||
const opaque key_label [KEY_LABEL_SZ + 1] = "key expansion";
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
|
||||
/*
|
||||
gcc 2.96 bails out because of two declarations of byte: yaSSL::byte and
|
||||
TaoCrypt::byte. TODO: define global types.hpp and move the declaration of
|
||||
'byte' there.
|
||||
*/
|
||||
using yaSSL::byte;
|
||||
#endif
|
||||
|
||||
|
||||
#endif // yaSSL_TYPES_HPP
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL buffer header implements input/output buffers to simulate streaming
|
||||
* with SSL types and sockets
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h> // memcpy
|
||||
#include "runtime.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "yassl_types.hpp"
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
|
||||
// Checking Policy should implement a check function that tests whether the
|
||||
// index is within the size limit of the array
|
||||
|
||||
void Check::check(uint i, uint limit)
|
||||
{
|
||||
assert(i < limit);
|
||||
}
|
||||
|
||||
|
||||
void NoCheck::check(uint, uint)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* input_buffer operates like a smart c style array with a checking option,
|
||||
* meant to be read from through [] with AUTO index or read().
|
||||
* Should only write to at/near construction with assign() or raw (e.g., recv)
|
||||
* followed by add_size with the number of elements added by raw write.
|
||||
*
|
||||
* Not using vector because need checked []access, offset, and the ability to
|
||||
* write to the buffer bulk wise and have the correct size
|
||||
*/
|
||||
|
||||
|
||||
input_buffer::input_buffer()
|
||||
: size_(0), current_(0), buffer_(0), end_(0)
|
||||
{}
|
||||
|
||||
|
||||
input_buffer::input_buffer(uint s)
|
||||
: size_(0), current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s)
|
||||
{}
|
||||
|
||||
|
||||
// with assign
|
||||
input_buffer::input_buffer(uint s, const byte* t, uint len)
|
||||
: size_(0), current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s)
|
||||
{
|
||||
assign(t, len);
|
||||
}
|
||||
|
||||
|
||||
input_buffer::~input_buffer()
|
||||
{
|
||||
ysArrayDelete(buffer_);
|
||||
}
|
||||
|
||||
|
||||
// users can pass defualt zero length buffer and then allocate
|
||||
void input_buffer::allocate(uint s)
|
||||
{
|
||||
assert(!buffer_); // find realloc error
|
||||
buffer_ = NEW_YS byte[s];
|
||||
end_ = buffer_ + s;
|
||||
}
|
||||
|
||||
|
||||
// for passing to raw writing functions at beginning, then use add_size
|
||||
byte* input_buffer::get_buffer() const
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
|
||||
|
||||
// after a raw write user can set NEW_YS size
|
||||
// if you know the size before the write use assign()
|
||||
void input_buffer::add_size(uint i)
|
||||
{
|
||||
check(size_ + i-1, get_capacity());
|
||||
size_ += i;
|
||||
}
|
||||
|
||||
|
||||
uint input_buffer::get_capacity() const
|
||||
{
|
||||
return end_ - buffer_;
|
||||
}
|
||||
|
||||
|
||||
uint input_buffer::get_current() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
|
||||
|
||||
uint input_buffer::get_size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
|
||||
uint input_buffer::get_remaining() const
|
||||
{
|
||||
return size_ - current_;
|
||||
}
|
||||
|
||||
|
||||
void input_buffer::set_current(uint i)
|
||||
{
|
||||
if (i)
|
||||
check(i - 1, size_);
|
||||
current_ = i;
|
||||
}
|
||||
|
||||
|
||||
// read only access through [], advance current
|
||||
// user passes in AUTO index for ease of use
|
||||
const byte& input_buffer::operator[](uint i)
|
||||
{
|
||||
assert (i == AUTO);
|
||||
check(current_, size_);
|
||||
return buffer_[current_++];
|
||||
}
|
||||
|
||||
|
||||
// end of input test
|
||||
bool input_buffer::eof()
|
||||
{
|
||||
return current_ >= size_;
|
||||
}
|
||||
|
||||
|
||||
// peek ahead
|
||||
byte input_buffer::peek() const
|
||||
{
|
||||
return buffer_[current_];
|
||||
}
|
||||
|
||||
|
||||
// write function, should use at/near construction
|
||||
void input_buffer::assign(const byte* t, uint s)
|
||||
{
|
||||
check(current_, get_capacity());
|
||||
add_size(s);
|
||||
memcpy(&buffer_[current_], t, s);
|
||||
}
|
||||
|
||||
|
||||
// use read to query input, adjusts current
|
||||
void input_buffer::read(byte* dst, uint length)
|
||||
{
|
||||
check(current_ + length - 1, size_);
|
||||
memcpy(dst, &buffer_[current_], length);
|
||||
current_ += length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* output_buffer operates like a smart c style array with a checking option.
|
||||
* Meant to be written to through [] with AUTO index or write().
|
||||
* Size (current) counter increases when written to. Can be constructed with
|
||||
* zero length buffer but be sure to allocate before first use.
|
||||
* Don't use add write for a couple bytes, use [] instead, way less overhead.
|
||||
*
|
||||
* Not using vector because need checked []access and the ability to
|
||||
* write to the buffer bulk wise and retain correct size
|
||||
*/
|
||||
|
||||
|
||||
output_buffer::output_buffer()
|
||||
: current_(0), buffer_(0), end_(0)
|
||||
{}
|
||||
|
||||
|
||||
// with allocate
|
||||
output_buffer::output_buffer(uint s)
|
||||
: current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s)
|
||||
{}
|
||||
|
||||
|
||||
// with assign
|
||||
output_buffer::output_buffer(uint s, const byte* t, uint len)
|
||||
: current_(0), buffer_(NEW_YS byte[s]), end_(buffer_+ s)
|
||||
{
|
||||
write(t, len);
|
||||
}
|
||||
|
||||
|
||||
output_buffer::~output_buffer()
|
||||
{
|
||||
ysArrayDelete(buffer_);
|
||||
}
|
||||
|
||||
|
||||
uint output_buffer::get_size() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
|
||||
|
||||
uint output_buffer::get_capacity() const
|
||||
{
|
||||
return end_ - buffer_;
|
||||
}
|
||||
|
||||
|
||||
void output_buffer::set_current(uint c)
|
||||
{
|
||||
check(c, get_capacity());
|
||||
current_ = c;
|
||||
}
|
||||
|
||||
|
||||
// users can pass defualt zero length buffer and then allocate
|
||||
void output_buffer::allocate(uint s)
|
||||
{
|
||||
assert(!buffer_); // find realloc error
|
||||
buffer_ = NEW_YS byte[s]; end_ = buffer_ + s;
|
||||
}
|
||||
|
||||
|
||||
// for passing to reading functions when finished
|
||||
const byte* output_buffer::get_buffer() const
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
|
||||
|
||||
// allow write access through [], update current
|
||||
// user passes in AUTO as index for ease of use
|
||||
byte& output_buffer::operator[](uint i)
|
||||
{
|
||||
assert(i == AUTO);
|
||||
check(current_, get_capacity());
|
||||
return buffer_[current_++];
|
||||
}
|
||||
|
||||
|
||||
// end of output test
|
||||
bool output_buffer::eof()
|
||||
{
|
||||
return current_ >= get_capacity();
|
||||
}
|
||||
|
||||
|
||||
void output_buffer::write(const byte* t, uint s)
|
||||
{
|
||||
check(current_ + s - 1, get_capacity());
|
||||
memcpy(&buffer_[current_], t, s);
|
||||
current_ += s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
+370
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* The certificate wrapper source implements certificate management functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "cert_wrapper.hpp"
|
||||
#include "yassl_int.hpp"
|
||||
#include "error.hpp"
|
||||
|
||||
#if defined(USE_CML_LIB)
|
||||
#include "cmapi_cpp.h"
|
||||
#else
|
||||
#include "asn.hpp"
|
||||
#include "file.hpp"
|
||||
#endif // USE_CML_LIB
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
x509::x509(uint sz) : length_(sz), buffer_(NEW_YS opaque[sz])
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
x509::~x509()
|
||||
{
|
||||
ysArrayDelete(buffer_);
|
||||
}
|
||||
|
||||
|
||||
x509::x509(const x509& that) : length_(that.length_),
|
||||
buffer_(NEW_YS opaque[length_])
|
||||
{
|
||||
memcpy(buffer_, that.buffer_, length_);
|
||||
}
|
||||
|
||||
|
||||
void x509::Swap(x509& that)
|
||||
{
|
||||
STL::swap(length_, that.length_);
|
||||
STL::swap(buffer_, that.buffer_);
|
||||
}
|
||||
|
||||
|
||||
x509& x509::operator=(const x509& that)
|
||||
{
|
||||
x509 temp(that);
|
||||
Swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
uint x509::get_length() const
|
||||
{
|
||||
return length_;
|
||||
}
|
||||
|
||||
|
||||
const opaque* x509::get_buffer() const
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
|
||||
|
||||
opaque* x509::use_buffer()
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
|
||||
|
||||
//CertManager
|
||||
CertManager::CertManager()
|
||||
: peerX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false),
|
||||
sendVerify_(false), verifyCallback_(0)
|
||||
{}
|
||||
|
||||
|
||||
CertManager::~CertManager()
|
||||
{
|
||||
ysDelete(peerX509_);
|
||||
|
||||
STL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ;
|
||||
|
||||
STL::for_each(peerList_.begin(), peerList_.end(), del_ptr_zero()) ;
|
||||
|
||||
STL::for_each(list_.begin(), list_.end(), del_ptr_zero()) ;
|
||||
}
|
||||
|
||||
|
||||
bool CertManager::verifyPeer() const
|
||||
{
|
||||
return verifyPeer_;
|
||||
}
|
||||
|
||||
|
||||
bool CertManager::verifyNone() const
|
||||
{
|
||||
return verifyNone_;
|
||||
}
|
||||
|
||||
|
||||
bool CertManager::failNoCert() const
|
||||
{
|
||||
return failNoCert_;
|
||||
}
|
||||
|
||||
|
||||
bool CertManager::sendVerify() const
|
||||
{
|
||||
return sendVerify_;
|
||||
}
|
||||
|
||||
|
||||
void CertManager::setVerifyPeer()
|
||||
{
|
||||
verifyPeer_ = true;
|
||||
}
|
||||
|
||||
|
||||
void CertManager::setVerifyNone()
|
||||
{
|
||||
verifyNone_ = true;
|
||||
}
|
||||
|
||||
|
||||
void CertManager::setFailNoCert()
|
||||
{
|
||||
failNoCert_ = true;
|
||||
}
|
||||
|
||||
|
||||
void CertManager::setSendVerify()
|
||||
{
|
||||
sendVerify_ = true;
|
||||
}
|
||||
|
||||
|
||||
void CertManager::setVerifyCallback(VerifyCallback vc)
|
||||
{
|
||||
verifyCallback_ = vc;
|
||||
}
|
||||
|
||||
|
||||
void CertManager::AddPeerCert(x509* x)
|
||||
{
|
||||
peerList_.push_back(x); // take ownership
|
||||
}
|
||||
|
||||
|
||||
void CertManager::CopySelfCert(const x509* x)
|
||||
{
|
||||
if (x)
|
||||
list_.push_back(NEW_YS x509(*x));
|
||||
}
|
||||
|
||||
|
||||
// add to signers
|
||||
int CertManager::CopyCaCert(const x509* x)
|
||||
{
|
||||
TaoCrypt::Source source(x->get_buffer(), x->get_length());
|
||||
TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_,
|
||||
TaoCrypt::CertDecoder::CA);
|
||||
|
||||
if (!cert.GetError().What()) {
|
||||
const TaoCrypt::PublicKey& key = cert.GetPublicKey();
|
||||
signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
|
||||
cert.GetCommonName(), cert.GetHash()));
|
||||
}
|
||||
// just don't add, not an error return cert.GetError().What();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const x509* CertManager::get_cert() const
|
||||
{
|
||||
return list_.front();
|
||||
}
|
||||
|
||||
|
||||
const opaque* CertManager::get_peerKey() const
|
||||
{
|
||||
return peerPublicKey_.get_buffer();
|
||||
}
|
||||
|
||||
|
||||
X509* CertManager::get_peerX509() const
|
||||
{
|
||||
return peerX509_;
|
||||
}
|
||||
|
||||
|
||||
SignatureAlgorithm CertManager::get_peerKeyType() const
|
||||
{
|
||||
return peerKeyType_;
|
||||
}
|
||||
|
||||
|
||||
SignatureAlgorithm CertManager::get_keyType() const
|
||||
{
|
||||
return keyType_;
|
||||
}
|
||||
|
||||
|
||||
uint CertManager::get_peerKeyLength() const
|
||||
{
|
||||
return peerPublicKey_.get_size();
|
||||
}
|
||||
|
||||
|
||||
const opaque* CertManager::get_privateKey() const
|
||||
{
|
||||
return privateKey_.get_buffer();
|
||||
}
|
||||
|
||||
|
||||
uint CertManager::get_privateKeyLength() const
|
||||
{
|
||||
return privateKey_.get_size();
|
||||
}
|
||||
|
||||
|
||||
// Validate the peer's certificate list, from root to peer (last to first)
|
||||
int CertManager::Validate()
|
||||
{
|
||||
CertList::reverse_iterator last = peerList_.rbegin();
|
||||
size_t count = peerList_.size();
|
||||
|
||||
while ( count > 1 ) {
|
||||
TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
|
||||
TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
|
||||
|
||||
if (int err = cert.GetError().What())
|
||||
return err;
|
||||
|
||||
const TaoCrypt::PublicKey& key = cert.GetPublicKey();
|
||||
signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
|
||||
cert.GetCommonName(), cert.GetHash()));
|
||||
++last;
|
||||
--count;
|
||||
}
|
||||
|
||||
if (count) {
|
||||
// peer's is at the front
|
||||
TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
|
||||
TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
|
||||
|
||||
int err = cert.GetError().What();
|
||||
if ( err )
|
||||
return err;
|
||||
|
||||
uint sz = cert.GetPublicKey().size();
|
||||
peerPublicKey_.allocate(sz);
|
||||
peerPublicKey_.assign(cert.GetPublicKey().GetKey(), sz);
|
||||
|
||||
if (cert.GetKeyType() == TaoCrypt::RSAk)
|
||||
peerKeyType_ = rsa_sa_algo;
|
||||
else
|
||||
peerKeyType_ = dsa_sa_algo;
|
||||
|
||||
size_t iSz = strlen(cert.GetIssuer()) + 1;
|
||||
size_t sSz = strlen(cert.GetCommonName()) + 1;
|
||||
int bSz = (int)strlen(cert.GetBeforeDate()) + 1;
|
||||
int aSz = (int)strlen(cert.GetAfterDate()) + 1;
|
||||
peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
|
||||
sSz, cert.GetBeforeDate(), bSz,
|
||||
cert.GetAfterDate(), aSz);
|
||||
|
||||
if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) {
|
||||
X509_STORE_CTX store;
|
||||
store.error = err;
|
||||
store.error_depth = static_cast<int>(count) - 1;
|
||||
store.current_cert = peerX509_;
|
||||
|
||||
int ok = verifyCallback_(0, &store);
|
||||
if (ok) return 0;
|
||||
}
|
||||
|
||||
if (err == TaoCrypt::SIG_OTHER_E) return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Set the private key
|
||||
int CertManager::SetPrivateKey(const x509& key)
|
||||
{
|
||||
privateKey_.allocate(key.get_length());
|
||||
privateKey_.assign(key.get_buffer(), key.get_length());
|
||||
|
||||
// set key type
|
||||
if (x509* cert = list_.front()) {
|
||||
TaoCrypt::Source source(cert->get_buffer(), cert->get_length());
|
||||
TaoCrypt::CertDecoder cd(source, false);
|
||||
cd.DecodeToKey();
|
||||
if (int err = cd.GetError().What())
|
||||
return err;
|
||||
if (cd.GetKeyType() == TaoCrypt::RSAk)
|
||||
keyType_ = rsa_sa_algo;
|
||||
else
|
||||
keyType_ = dsa_sa_algo;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Store OpenSSL type peer's cert
|
||||
void CertManager::setPeerX509(X509* x)
|
||||
{
|
||||
assert(peerX509_ == 0);
|
||||
if (x == 0) return;
|
||||
|
||||
X509_NAME* issuer = x->GetIssuer();
|
||||
X509_NAME* subject = x->GetSubject();
|
||||
ASN1_STRING* before = x->GetBefore();
|
||||
ASN1_STRING* after = x->GetAfter();
|
||||
|
||||
peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
|
||||
subject->GetName(), subject->GetLength(), (const char*) before->data,
|
||||
before->length, (const char*) after->data, after->length);
|
||||
}
|
||||
|
||||
|
||||
#if defined(USE_CML_LIB)
|
||||
|
||||
// Get the peer's certificate, extract and save public key
|
||||
void CertManager::SetPeerKey()
|
||||
{
|
||||
// first cert is the peer's
|
||||
x509* main = peerList_.front();
|
||||
|
||||
Bytes_struct cert;
|
||||
cert.num = main->get_length();
|
||||
cert.data = main->set_buffer();
|
||||
|
||||
CML::Certificate cm(cert);
|
||||
const CML::ASN::Cert& raw = cm.base();
|
||||
CTIL::CSM_Buffer key = raw.pubKeyInfo.key;
|
||||
|
||||
uint sz;
|
||||
opaque* key_buffer = reinterpret_cast<opaque*>(key.Get(sz));
|
||||
peerPublicKey_.allocate(sz);
|
||||
peerPublicKey_.assign(key_buffer, sz);
|
||||
}
|
||||
|
||||
|
||||
#endif // USE_CML_LIB
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
+1013
File diff suppressed because it is too large
Load Diff
+4
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
To make libtool always use a C++ linker when compiling with yaSSL we need
|
||||
to add a dummy C++ file to the source list.
|
||||
*/
|
||||
+1117
File diff suppressed because it is too large
Load Diff
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* Locking functions
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "lock.hpp"
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
#ifdef MULTI_THREADED
|
||||
#ifdef _WIN32
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
InitializeCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
DeleteCriticalSection(&cs_);
|
||||
}
|
||||
|
||||
|
||||
Mutex::Lock::Lock(Mutex& lm) : mutex_(lm)
|
||||
{
|
||||
EnterCriticalSection(&mutex_.cs_);
|
||||
}
|
||||
|
||||
|
||||
Mutex::Lock::~Lock()
|
||||
{
|
||||
LeaveCriticalSection(&mutex_.cs_);
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
pthread_mutex_init(&mutex_, 0);
|
||||
}
|
||||
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
|
||||
Mutex::Lock::Lock(Mutex& lm) : mutex_(lm)
|
||||
{
|
||||
pthread_mutex_lock(&mutex_.mutex_);
|
||||
}
|
||||
|
||||
|
||||
Mutex::Lock::~Lock()
|
||||
{
|
||||
pthread_mutex_unlock(&mutex_.mutex_);
|
||||
}
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // MULTI_THREADED
|
||||
|
||||
|
||||
|
||||
} // namespace yaSSL
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* Debug logging functions
|
||||
*/
|
||||
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#ifdef YASSL_LOG
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
#ifdef YASSL_LOG
|
||||
|
||||
enum { MAX_MSG = 81 };
|
||||
|
||||
Log::Log(const char* str)
|
||||
{
|
||||
log_ = fopen(str, "w");
|
||||
Trace("********** Logger Attached **********");
|
||||
}
|
||||
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
Trace("********** Logger Detached **********");
|
||||
fclose(log_);
|
||||
}
|
||||
|
||||
|
||||
// Trace a message
|
||||
void Log::Trace(const char* str)
|
||||
{
|
||||
if (!log_) return;
|
||||
|
||||
time_t clicks = time(0);
|
||||
char timeStr[32];
|
||||
|
||||
// get rid of newline
|
||||
strncpy(timeStr, ctime(&clicks), sizeof(timeStr));
|
||||
unsigned int len = strlen(timeStr);
|
||||
timeStr[len - 1] = 0;
|
||||
|
||||
char msg[MAX_MSG];
|
||||
|
||||
strncpy(msg, timeStr, sizeof(timeStr));
|
||||
strncat(msg, ":", 1);
|
||||
strncat(msg, str, MAX_MSG - sizeof(timeStr) - 2);
|
||||
strncat(msg, "\n", 1);
|
||||
msg[MAX_MSG - 1] = 0;
|
||||
|
||||
fputs(msg, log_);
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__MACH__) || defined(__hpux__)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
|
||||
// write tcp address
|
||||
void Log::ShowTCP(socket_t fd, bool ended)
|
||||
{
|
||||
sockaddr_in peeraddr;
|
||||
socklen_t len = sizeof(peeraddr);
|
||||
if (getpeername(fd, (sockaddr*)&peeraddr, &len) != 0)
|
||||
return;
|
||||
|
||||
const char* p = reinterpret_cast<const char*>(&peeraddr.sin_addr);
|
||||
char msg[MAX_MSG];
|
||||
char number[16];
|
||||
|
||||
if (ended)
|
||||
strncpy(msg, "yaSSL conn DONE w/ peer ", 26);
|
||||
else
|
||||
strncpy(msg, "yaSSL conn BEGUN w/ peer ", 26);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
sprintf(number, "%u", static_cast<unsigned short>(p[i]));
|
||||
strncat(msg, number, 8);
|
||||
if (i < 3)
|
||||
strncat(msg, ".", 1);
|
||||
}
|
||||
strncat(msg, " port ", 8);
|
||||
sprintf(number, "%d", htons(peeraddr.sin_port));
|
||||
strncat(msg, number, 8);
|
||||
|
||||
msg[MAX_MSG - 1] = 0;
|
||||
Trace(msg);
|
||||
}
|
||||
|
||||
|
||||
// log processed data
|
||||
void Log::ShowData(uint bytes, bool sent)
|
||||
{
|
||||
char msg[MAX_MSG];
|
||||
char number[16];
|
||||
|
||||
if (sent)
|
||||
strncpy(msg, "Sent ", 10);
|
||||
else
|
||||
strncpy(msg, "Received ", 10);
|
||||
sprintf(number, "%u", bytes);
|
||||
strncat(msg, number, 8);
|
||||
strncat(msg, " bytes of application data", 27);
|
||||
|
||||
msg[MAX_MSG - 1] = 0;
|
||||
Trace(msg);
|
||||
}
|
||||
|
||||
|
||||
#else // no YASSL_LOG
|
||||
|
||||
|
||||
Log::Log(const char*) {}
|
||||
Log::~Log() {}
|
||||
void Log::Trace(const char*) {}
|
||||
void Log::ShowTCP(socket_t, bool) {}
|
||||
void Log::ShowData(uint, bool) {}
|
||||
|
||||
|
||||
#endif // YASSL_LOG
|
||||
} // namespace
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* The socket wrapper source implements a Socket class that hides the
|
||||
* differences between Berkely style sockets and Windows sockets, allowing
|
||||
* transparent TCP access.
|
||||
*/
|
||||
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "socket_wrapper.hpp"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#if defined(__sun) || defined(__SCO_VERSION__) || defined(__NETWARE__)
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
const int SOCKET_EINVAL = WSAEINVAL;
|
||||
const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;
|
||||
const int SOCKET_EAGAIN = WSAEWOULDBLOCK;
|
||||
#else
|
||||
const int SOCKET_EINVAL = EINVAL;
|
||||
const int SOCKET_EWOULDBLOCK = EWOULDBLOCK;
|
||||
const int SOCKET_EAGAIN = EAGAIN;
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
Socket::Socket(socket_t s)
|
||||
: socket_(s), wouldBlock_(false), nonBlocking_(false)
|
||||
{}
|
||||
|
||||
|
||||
void Socket::set_fd(socket_t s)
|
||||
{
|
||||
socket_ = s;
|
||||
}
|
||||
|
||||
|
||||
socket_t Socket::get_fd() const
|
||||
{
|
||||
return socket_;
|
||||
}
|
||||
|
||||
|
||||
Socket::~Socket()
|
||||
{
|
||||
// don't close automatically now
|
||||
}
|
||||
|
||||
|
||||
void Socket::closeSocket()
|
||||
{
|
||||
if (socket_ != INVALID_SOCKET) {
|
||||
#ifdef _WIN32
|
||||
closesocket(socket_);
|
||||
#else
|
||||
close(socket_);
|
||||
#endif
|
||||
socket_ = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint Socket::get_ready() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
unsigned long ready = 0;
|
||||
ioctlsocket(socket_, FIONREAD, &ready);
|
||||
#else
|
||||
/*
|
||||
64-bit Solaris requires the variable passed to
|
||||
FIONREAD be a 32-bit value.
|
||||
*/
|
||||
unsigned int ready = 0;
|
||||
ioctl(socket_, FIONREAD, &ready);
|
||||
#endif
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
|
||||
uint Socket::send(const byte* buf, unsigned int sz, int flags) const
|
||||
{
|
||||
const byte* pos = buf;
|
||||
const byte* end = pos + sz;
|
||||
|
||||
while (pos != end) {
|
||||
int sent = ::send(socket_, reinterpret_cast<const char *>(pos),
|
||||
static_cast<int>(end - pos), flags);
|
||||
|
||||
if (sent == -1)
|
||||
return 0;
|
||||
|
||||
pos += sent;
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
uint Socket::receive(byte* buf, unsigned int sz, int flags)
|
||||
{
|
||||
wouldBlock_ = false;
|
||||
|
||||
int recvd = ::recv(socket_, reinterpret_cast<char *>(buf), sz, flags);
|
||||
|
||||
// idea to seperate error from would block by [email protected]
|
||||
if (recvd == -1) {
|
||||
if (get_lastError() == SOCKET_EWOULDBLOCK ||
|
||||
get_lastError() == SOCKET_EAGAIN) {
|
||||
wouldBlock_ = true; // would have blocked this time only
|
||||
nonBlocking_ = true; // socket nonblocking, win32 only way to tell
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (recvd == 0)
|
||||
return static_cast<uint>(-1);
|
||||
|
||||
return recvd;
|
||||
}
|
||||
|
||||
|
||||
// wait if blocking for input, return false for error
|
||||
bool Socket::wait()
|
||||
{
|
||||
byte b;
|
||||
return receive(&b, 1, MSG_PEEK) != static_cast<uint>(-1);
|
||||
}
|
||||
|
||||
|
||||
void Socket::shutDown(int how)
|
||||
{
|
||||
shutdown(socket_, how);
|
||||
}
|
||||
|
||||
|
||||
int Socket::get_lastError()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return WSAGetLastError();
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Socket::WouldBlock() const
|
||||
{
|
||||
return wouldBlock_;
|
||||
}
|
||||
|
||||
|
||||
bool Socket::IsNonBlocking() const
|
||||
{
|
||||
return nonBlocking_;
|
||||
}
|
||||
|
||||
|
||||
void Socket::set_lastError(int errorCode)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSASetLastError(errorCode);
|
||||
#else
|
||||
errno = errorCode;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
+1672
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* Explicit template instantiation requests
|
||||
*/
|
||||
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "handshake.hpp"
|
||||
#include "yassl_int.hpp"
|
||||
#include "crypto_wrapper.hpp"
|
||||
#include "hmac.hpp"
|
||||
#include "md5.hpp"
|
||||
#include "sha.hpp"
|
||||
#include "ripemd.hpp"
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
|
||||
namespace mySTL {
|
||||
template class list<unsigned char*>;
|
||||
template yaSSL::del_ptr_zero for_each(mySTL::list<unsigned char*>::iterator, mySTL::list<unsigned char*>::iterator, yaSSL::del_ptr_zero);
|
||||
template pair<int, yaSSL::Message* (*)()>* uninit_copy<mySTL::pair<int, yaSSL::Message* (*)()>*, mySTL::pair<int, yaSSL::Message* (*)()>*>(mySTL::pair<int, yaSSL::Message* (*)()>*, mySTL::pair<int, yaSSL::Message* (*)()>*, mySTL::pair<int, yaSSL::Message* (*)()>*);
|
||||
template pair<int, yaSSL::HandShakeBase* (*)()>* uninit_copy<mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*, mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*>(mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*, mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*, mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*);
|
||||
template void destroy<mySTL::pair<int, yaSSL::Message* (*)()>*>(mySTL::pair<int, yaSSL::Message* (*)()>*, mySTL::pair<int, yaSSL::Message* (*)()>*);
|
||||
template void destroy<mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*>(mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*, mySTL::pair<int, yaSSL::HandShakeBase* (*)()>*);
|
||||
template pair<int, yaSSL::ServerKeyBase* (*)()>* uninit_copy<mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*>(mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*);
|
||||
template void destroy<mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*>(mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ServerKeyBase* (*)()>*);
|
||||
template pair<int, yaSSL::ClientKeyBase* (*)()>* uninit_copy<mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*>(mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*);
|
||||
template class list<TaoCrypt::Signer*>;
|
||||
template class list<yaSSL::SSL_SESSION*>;
|
||||
template class list<yaSSL::input_buffer*>;
|
||||
template class list<yaSSL::output_buffer*>;
|
||||
template class list<yaSSL::x509*>;
|
||||
template class list<yaSSL::Digest*>;
|
||||
template class list<yaSSL::BulkCipher*>;
|
||||
template void destroy<mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*>(mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*, mySTL::pair<int, yaSSL::ClientKeyBase* (*)()>*);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<TaoCrypt::Signer*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<TaoCrypt::Signer*>::iterator, mySTL::list<TaoCrypt::Signer*>::iterator, yaSSL::del_ptr_zero);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::SSL_SESSION*>::iterator, mySTL::list<yaSSL::SSL_SESSION*>::iterator, yaSSL::del_ptr_zero);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::input_buffer*>::iterator, mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::del_ptr_zero);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::output_buffer*>::iterator, mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::del_ptr_zero);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::x509*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::x509*>::iterator, mySTL::list<yaSSL::x509*>::iterator, yaSSL::del_ptr_zero);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::Digest*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::Digest*>::iterator, mySTL::list<yaSSL::Digest*>::iterator, yaSSL::del_ptr_zero);
|
||||
template yaSSL::del_ptr_zero for_each<mySTL::list<yaSSL::BulkCipher*>::iterator, yaSSL::del_ptr_zero>(mySTL::list<yaSSL::BulkCipher*>::iterator, mySTL::list<yaSSL::BulkCipher*>::iterator, yaSSL::del_ptr_zero);
|
||||
template bool list<yaSSL::ThreadError>::erase(list<yaSSL::ThreadError>::iterator);
|
||||
template void list<yaSSL::ThreadError>::push_back(yaSSL::ThreadError);
|
||||
template void list<yaSSL::ThreadError>::pop_front();
|
||||
template void list<yaSSL::ThreadError>::pop_back();
|
||||
template list<yaSSL::ThreadError>::~list();
|
||||
template pair<int, yaSSL::Message* (*)()>* GetArrayMemory<pair<int, yaSSL::Message* (*)()> >(size_t);
|
||||
template void FreeArrayMemory<pair<int, yaSSL::Message* (*)()> >(pair<int, yaSSL::Message* (*)()>*);
|
||||
template pair<int, yaSSL::HandShakeBase* (*)()>* GetArrayMemory<pair<int, yaSSL::HandShakeBase* (*)()> >(size_t);
|
||||
template void FreeArrayMemory<pair<int, yaSSL::HandShakeBase* (*)()> >(pair<int, yaSSL::HandShakeBase* (*)()>*);
|
||||
template pair<int, yaSSL::ServerKeyBase* (*)()>* GetArrayMemory<pair<int, yaSSL::ServerKeyBase* (*)()> >(size_t);
|
||||
template void FreeArrayMemory<pair<int, yaSSL::ServerKeyBase* (*)()> >(pair<int, yaSSL::ServerKeyBase* (*)()>*);
|
||||
template pair<int, yaSSL::ClientKeyBase* (*)()>* GetArrayMemory<pair<int, yaSSL::ClientKeyBase* (*)()> >(size_t);
|
||||
template void FreeArrayMemory<pair<int, yaSSL::ClientKeyBase* (*)()> >(pair<int, yaSSL::ClientKeyBase* (*)()>*);
|
||||
}
|
||||
|
||||
namespace yaSSL {
|
||||
template void ysDelete<SSL_CTX>(yaSSL::SSL_CTX*);
|
||||
template void ysDelete<SSL>(yaSSL::SSL*);
|
||||
template void ysDelete<BIGNUM>(yaSSL::BIGNUM*);
|
||||
template void ysDelete<unsigned char>(unsigned char*);
|
||||
template void ysDelete<DH>(yaSSL::DH*);
|
||||
template void ysDelete<TaoCrypt::Signer>(TaoCrypt::Signer*);
|
||||
template void ysDelete<SSL_SESSION>(yaSSL::SSL_SESSION*);
|
||||
template void ysDelete<input_buffer>(input_buffer*);
|
||||
template void ysDelete<output_buffer>(output_buffer*);
|
||||
template void ysDelete<x509>(x509*);
|
||||
template void ysDelete<Auth>(Auth*);
|
||||
template void ysDelete<HandShakeBase>(HandShakeBase*);
|
||||
template void ysDelete<ServerKeyBase>(ServerKeyBase*);
|
||||
template void ysDelete<ClientKeyBase>(ClientKeyBase*);
|
||||
template void ysDelete<SSL_METHOD>(SSL_METHOD*);
|
||||
template void ysDelete<DiffieHellman>(DiffieHellman*);
|
||||
template void ysDelete<BulkCipher>(BulkCipher*);
|
||||
template void ysDelete<Digest>(Digest*);
|
||||
template void ysDelete<X509>(X509*);
|
||||
template void ysDelete<Message>(Message*);
|
||||
template void ysDelete<sslFactory>(sslFactory*);
|
||||
template void ysDelete<Sessions>(Sessions*);
|
||||
template void ysDelete<Errors>(Errors*);
|
||||
template void ysArrayDelete<unsigned char>(unsigned char*);
|
||||
template void ysArrayDelete<char>(char*);
|
||||
|
||||
template int min<int>(int, int);
|
||||
template uint16 min<uint16>(uint16, uint16);
|
||||
template unsigned int min<unsigned int>(unsigned int, unsigned int);
|
||||
template unsigned long min<unsigned long>(unsigned long, unsigned long);
|
||||
}
|
||||
|
||||
#endif // HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* timer.cpp implements a high res and low res timer
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "timer.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
timer_d timer()
|
||||
{
|
||||
static bool init(false);
|
||||
static LARGE_INTEGER freq;
|
||||
|
||||
if (!init) {
|
||||
QueryPerformanceFrequency(&freq);
|
||||
init = true;
|
||||
}
|
||||
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
|
||||
return static_cast<double>(count.QuadPart) / freq.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
uint lowResTimer()
|
||||
{
|
||||
return static_cast<uint>(timer());
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
timer_d timer()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
|
||||
return static_cast<double>(tv.tv_sec)
|
||||
+ static_cast<double>(tv.tv_usec) / 1000000;
|
||||
}
|
||||
|
||||
|
||||
uint lowResTimer()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
|
||||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
} // namespace yaSSL
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL implements external API
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "yassl.hpp"
|
||||
#include "yassl_int.hpp"
|
||||
#include "handshake.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "openssl/ssl.h" // get rid of this
|
||||
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
|
||||
struct Base {
|
||||
SSL_METHOD* method_;
|
||||
SSL_CTX* ctx_;
|
||||
SSL* ssl_;
|
||||
|
||||
char* ca_;
|
||||
char* cert_;
|
||||
char* key_;
|
||||
|
||||
DH* dh_;
|
||||
|
||||
Base() : method_(0), ctx_(0), ssl_(0), ca_(0), cert_(0), key_(0), dh_(0)
|
||||
{}
|
||||
|
||||
~Base()
|
||||
{
|
||||
if (dh_) DH_free(dh_);
|
||||
delete[] key_;
|
||||
delete[] cert_;
|
||||
delete[] ca_;
|
||||
SSL_CTX_free(ctx_); // frees method_ too
|
||||
SSL_free(ssl_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void SetDH(Base&);
|
||||
|
||||
void SetUpBase(Base& base, ConnectionEnd end, SOCKET_T s)
|
||||
{
|
||||
base.method_ = new SSL_METHOD(end, ProtocolVersion(3,1));
|
||||
base.ctx_ = new SSL_CTX(base.method_);
|
||||
|
||||
if (base.ca_)
|
||||
if (SSL_CTX_load_verify_locations(base.ctx_,
|
||||
base.ca_, 0) != SSL_SUCCESS) assert(0);
|
||||
if (base.cert_)
|
||||
if (SSL_CTX_use_certificate_file(base.ctx_,
|
||||
base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0);
|
||||
if (base.key_)
|
||||
if (SSL_CTX_use_PrivateKey_file(base.ctx_, base.key_,
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0);
|
||||
|
||||
if (end == server_end) SetDH(base);
|
||||
|
||||
base.ssl_ = new SSL(base.ctx_);
|
||||
base.ssl_->useSocket().set_fd(s);
|
||||
}
|
||||
|
||||
|
||||
void SetDH(Base& base)
|
||||
{
|
||||
static unsigned char dh512_p[] =
|
||||
{
|
||||
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
|
||||
0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
|
||||
0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
|
||||
0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
|
||||
0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
|
||||
0x47,0x74,0xE8,0x33,
|
||||
};
|
||||
|
||||
static unsigned char dh512_g[] =
|
||||
{
|
||||
0x02,
|
||||
};
|
||||
|
||||
if ( (base.dh_ = DH_new()) ) {
|
||||
base.dh_->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0);
|
||||
base.dh_->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0);
|
||||
}
|
||||
if (!base.dh_->p || !base.dh_->g) {
|
||||
DH_free(base.dh_);
|
||||
base.dh_ = 0;
|
||||
}
|
||||
SSL_CTX_set_tmp_dh(base.ctx_, base.dh_);
|
||||
}
|
||||
|
||||
|
||||
void NewCopy(char*& dst, const char* src)
|
||||
{
|
||||
size_t len = strlen(src) + 1;
|
||||
dst = new char[len];
|
||||
|
||||
strncpy(dst, src, len);
|
||||
}
|
||||
|
||||
|
||||
// Client Implementation
|
||||
struct Client::ClientImpl {
|
||||
Base base_;
|
||||
};
|
||||
|
||||
|
||||
Client::Client() : pimpl_(new ClientImpl)
|
||||
{}
|
||||
|
||||
|
||||
Client::~Client() { delete pimpl_; }
|
||||
|
||||
|
||||
int Client::Connect(SOCKET_T s)
|
||||
{
|
||||
SetUpBase(pimpl_->base_, client_end, s);
|
||||
return SSL_connect(pimpl_->base_.ssl_);
|
||||
}
|
||||
|
||||
|
||||
int Client::Write(const void* buffer, int sz)
|
||||
{
|
||||
return sendData(*pimpl_->base_.ssl_, buffer, sz);
|
||||
}
|
||||
|
||||
|
||||
int Client::Read(void* buffer, int sz)
|
||||
{
|
||||
Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer));
|
||||
return receiveData(*pimpl_->base_.ssl_, data);
|
||||
}
|
||||
|
||||
|
||||
void Client::SetCA(const char* name)
|
||||
{
|
||||
NewCopy(pimpl_->base_.ca_, name);
|
||||
}
|
||||
|
||||
|
||||
void Client::SetCert(const char* name)
|
||||
{
|
||||
NewCopy(pimpl_->base_.cert_, name);
|
||||
}
|
||||
|
||||
|
||||
void Client::SetKey(const char* name)
|
||||
{
|
||||
NewCopy(pimpl_->base_.key_, name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Server Implementation
|
||||
struct Server::ServerImpl {
|
||||
Base base_;
|
||||
};
|
||||
|
||||
|
||||
Server::Server() : pimpl_(new ServerImpl)
|
||||
{}
|
||||
|
||||
|
||||
Server::~Server() { delete pimpl_; }
|
||||
|
||||
|
||||
int Server::Accept(SOCKET_T s)
|
||||
{
|
||||
SetUpBase(pimpl_->base_, server_end, s);
|
||||
return SSL_accept(pimpl_->base_.ssl_);
|
||||
}
|
||||
|
||||
|
||||
int Server::Write(const void* buffer, int sz)
|
||||
{
|
||||
return sendData(*pimpl_->base_.ssl_, buffer, sz);
|
||||
}
|
||||
|
||||
|
||||
int Server::Read(void* buffer, int sz)
|
||||
{
|
||||
Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer));
|
||||
return receiveData(*pimpl_->base_.ssl_, data);
|
||||
}
|
||||
|
||||
|
||||
void Server::SetCA(const char* name)
|
||||
{
|
||||
NewCopy(pimpl_->base_.ca_, name);
|
||||
}
|
||||
|
||||
|
||||
void Server::SetCert(const char* name)
|
||||
{
|
||||
NewCopy(pimpl_->base_.cert_, name);
|
||||
}
|
||||
|
||||
|
||||
void Server::SetKey(const char* name)
|
||||
{
|
||||
NewCopy(pimpl_->base_.key_, name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace yaSSL
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* yaSSL error implements and an exception class
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "yassl_error.hpp"
|
||||
#include "error.hpp" // TaoCrypt error numbers
|
||||
#include "openssl/ssl.h" // SSL_ERROR_WANT_READ
|
||||
#include <string.h> // strncpy
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
/* may bring back in future
|
||||
Error::Error(const char* s, YasslError e, Library l)
|
||||
: mySTL::runtime_error(s), error_(e), lib_(l)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
YasslError Error::get_number() const
|
||||
{
|
||||
return error_;
|
||||
}
|
||||
|
||||
|
||||
Library Error::get_lib() const
|
||||
{
|
||||
|
||||
return lib_;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void SetErrorString(YasslError error, char* buffer)
|
||||
{
|
||||
using namespace TaoCrypt;
|
||||
const int max = MAX_ERROR_SZ; // shorthand
|
||||
|
||||
switch (error) {
|
||||
|
||||
// yaSSL proper errors
|
||||
case range_error :
|
||||
strncpy(buffer, "buffer index error, out of range", max);
|
||||
break;
|
||||
|
||||
case realloc_error :
|
||||
strncpy(buffer, "trying to realloc a fixed buffer", max);
|
||||
break;
|
||||
|
||||
case factory_error :
|
||||
strncpy(buffer, "unknown factory create request", max);
|
||||
break;
|
||||
|
||||
case unknown_cipher :
|
||||
strncpy(buffer, "trying to use an unknown cipher", max);
|
||||
break;
|
||||
|
||||
case prefix_error :
|
||||
strncpy(buffer, "bad master secret derivation, prefix too big", max);
|
||||
break;
|
||||
|
||||
case record_layer :
|
||||
strncpy(buffer, "record layer not ready yet", max);
|
||||
break;
|
||||
|
||||
case handshake_layer :
|
||||
strncpy(buffer, "handshake layer not ready yet", max);
|
||||
break;
|
||||
|
||||
case out_of_order :
|
||||
strncpy(buffer, "handshake message received in wrong order", max);
|
||||
break;
|
||||
|
||||
case bad_input :
|
||||
strncpy(buffer, "bad cipher suite input", max);
|
||||
break;
|
||||
|
||||
case match_error :
|
||||
strncpy(buffer, "unable to match a supported cipher suite", max);
|
||||
break;
|
||||
|
||||
case no_key_file :
|
||||
strncpy(buffer, "the server needs a private key file", max);
|
||||
break;
|
||||
|
||||
case verify_error :
|
||||
strncpy(buffer, "unable to verify peer checksum", max);
|
||||
break;
|
||||
|
||||
case send_error :
|
||||
strncpy(buffer, "socket layer send error", max);
|
||||
break;
|
||||
|
||||
case receive_error :
|
||||
strncpy(buffer, "socket layer receive error", max);
|
||||
break;
|
||||
|
||||
case certificate_error :
|
||||
strncpy(buffer, "unable to proccess cerificate", max);
|
||||
break;
|
||||
|
||||
case privateKey_error :
|
||||
strncpy(buffer, "unable to proccess private key, bad format", max);
|
||||
break;
|
||||
|
||||
case badVersion_error :
|
||||
strncpy(buffer, "protocl version mismatch", max);
|
||||
break;
|
||||
|
||||
case compress_error :
|
||||
strncpy(buffer, "compression error", max);
|
||||
break;
|
||||
|
||||
case decompress_error :
|
||||
strncpy(buffer, "decompression error", max);
|
||||
break;
|
||||
|
||||
case pms_version_error :
|
||||
strncpy(buffer, "bad PreMasterSecret version error", max);
|
||||
break;
|
||||
|
||||
// openssl errors
|
||||
case SSL_ERROR_WANT_READ :
|
||||
strncpy(buffer, "the read operation would block", max);
|
||||
break;
|
||||
|
||||
case CERTFICATE_ERROR :
|
||||
strncpy(buffer, "Unable to verify certificate", max);
|
||||
break;
|
||||
|
||||
// TaoCrypt errors
|
||||
case NO_ERROR_E :
|
||||
strncpy(buffer, "not in error state", max);
|
||||
break;
|
||||
|
||||
case WINCRYPT_E :
|
||||
strncpy(buffer, "bad wincrypt acquire", max);
|
||||
break;
|
||||
|
||||
case CRYPTGEN_E :
|
||||
strncpy(buffer, "CryptGenRandom error", max);
|
||||
break;
|
||||
|
||||
case OPEN_RAN_E :
|
||||
strncpy(buffer, "unable to use random device", max);
|
||||
break;
|
||||
|
||||
case READ_RAN_E :
|
||||
strncpy(buffer, "unable to use random device", max);
|
||||
break;
|
||||
|
||||
case INTEGER_E :
|
||||
strncpy(buffer, "ASN: bad DER Integer Header", max);
|
||||
break;
|
||||
|
||||
case SEQUENCE_E :
|
||||
strncpy(buffer, "ASN: bad Sequence Header", max);
|
||||
break;
|
||||
|
||||
case SET_E :
|
||||
strncpy(buffer, "ASN: bad Set Header", max);
|
||||
break;
|
||||
|
||||
case VERSION_E :
|
||||
strncpy(buffer, "ASN: version length not 1", max);
|
||||
break;
|
||||
|
||||
case SIG_OID_E :
|
||||
strncpy(buffer, "ASN: signature OID mismatch", max);
|
||||
break;
|
||||
|
||||
case BIT_STR_E :
|
||||
strncpy(buffer, "ASN: bad BitString Header", max);
|
||||
break;
|
||||
|
||||
case UNKNOWN_OID_E :
|
||||
strncpy(buffer, "ASN: unknown key OID type", max);
|
||||
break;
|
||||
|
||||
case OBJECT_ID_E :
|
||||
strncpy(buffer, "ASN: bad Ojbect ID Header", max);
|
||||
break;
|
||||
|
||||
case TAG_NULL_E :
|
||||
strncpy(buffer, "ASN: expected TAG NULL", max);
|
||||
break;
|
||||
|
||||
case EXPECT_0_E :
|
||||
strncpy(buffer, "ASN: expected 0", max);
|
||||
break;
|
||||
|
||||
case OCTET_STR_E :
|
||||
strncpy(buffer, "ASN: bad Octet String Header", max);
|
||||
break;
|
||||
|
||||
case TIME_E :
|
||||
strncpy(buffer, "ASN: bad TIME", max);
|
||||
break;
|
||||
|
||||
case DATE_SZ_E :
|
||||
strncpy(buffer, "ASN: bad Date Size", max);
|
||||
break;
|
||||
|
||||
case SIG_LEN_E :
|
||||
strncpy(buffer, "ASN: bad Signature Length", max);
|
||||
break;
|
||||
|
||||
case UNKOWN_SIG_E :
|
||||
strncpy(buffer, "ASN: unknown signature OID", max);
|
||||
break;
|
||||
|
||||
case UNKOWN_HASH_E :
|
||||
strncpy(buffer, "ASN: unknown hash OID", max);
|
||||
break;
|
||||
|
||||
case DSA_SZ_E :
|
||||
strncpy(buffer, "ASN: bad DSA r or s size", max);
|
||||
break;
|
||||
|
||||
case BEFORE_DATE_E :
|
||||
strncpy(buffer, "ASN: before date in the future", max);
|
||||
break;
|
||||
|
||||
case AFTER_DATE_E :
|
||||
strncpy(buffer, "ASN: after date in the past", max);
|
||||
break;
|
||||
|
||||
case SIG_CONFIRM_E :
|
||||
strncpy(buffer, "ASN: bad self signature confirmation", max);
|
||||
break;
|
||||
|
||||
case SIG_OTHER_E :
|
||||
strncpy(buffer, "ASN: bad other signature confirmation", max);
|
||||
break;
|
||||
|
||||
case CONTENT_E :
|
||||
strncpy(buffer, "bad content processing", max);
|
||||
break;
|
||||
|
||||
case PEM_E :
|
||||
strncpy(buffer, "bad PEM format processing", max);
|
||||
break;
|
||||
|
||||
default :
|
||||
strncpy(buffer, "unknown error number", max);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace yaSSL
|
||||
+2287
File diff suppressed because it is too large
Load Diff
+2580
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* aes.hpp defines AES
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_AES_HPP
|
||||
#define TAO_CRYPT_AES_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "modes.hpp"
|
||||
|
||||
|
||||
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
|
||||
#define DO_AES_ASM
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
enum { AES_BLOCK_SIZE = 16 };
|
||||
|
||||
|
||||
// AES encryption and decryption, see FIPS-197
|
||||
class AES : public Mode_BASE {
|
||||
public:
|
||||
enum { BLOCK_SIZE = AES_BLOCK_SIZE };
|
||||
|
||||
AES(CipherDir DIR, Mode MODE)
|
||||
: Mode_BASE(BLOCK_SIZE, DIR, MODE) {}
|
||||
|
||||
#ifdef DO_AES_ASM
|
||||
void Process(byte*, const byte*, word32);
|
||||
#endif
|
||||
void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
|
||||
void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
|
||||
private:
|
||||
static const word32 rcon_[];
|
||||
|
||||
word32 rounds_;
|
||||
word32 key_[60]; // max size
|
||||
|
||||
static const word32 Te[5][256];
|
||||
static const word32 Td[5][256];
|
||||
|
||||
static const word32* Te0;
|
||||
static const word32* Te1;
|
||||
static const word32* Te2;
|
||||
static const word32* Te3;
|
||||
static const word32* Te4;
|
||||
|
||||
static const word32* Td0;
|
||||
static const word32* Td1;
|
||||
static const word32* Td2;
|
||||
static const word32* Td3;
|
||||
static const word32* Td4;
|
||||
|
||||
void encrypt(const byte*, const byte*, byte*) const;
|
||||
void AsmEncrypt(const byte*, byte*, void*) const;
|
||||
void decrypt(const byte*, const byte*, byte*) const;
|
||||
void AsmDecrypt(const byte*, byte*, void*) const;
|
||||
|
||||
void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
|
||||
|
||||
AES(const AES&); // hide copy
|
||||
AES& operator=(const AES&); // and assign
|
||||
};
|
||||
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, AES, ECB> AES_ECB_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, AES, ECB> AES_ECB_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, AES, CBC> AES_CBC_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, AES, CBC> AES_CBC_Decryption;
|
||||
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
||||
#endif // TAO_CRYPT_AES_HPP
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* based on Wei Dai's algebra.h from CryptoPP */
|
||||
|
||||
#ifndef TAO_CRYPT_ALGEBRA_HPP
|
||||
#define TAO_CRYPT_ALGEBRA_HPP
|
||||
|
||||
#include "integer.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// "const Element&" returned by member functions are references
|
||||
// to internal data members. Since each object may have only
|
||||
// one such data member for holding results, the following code
|
||||
// will produce incorrect results:
|
||||
// abcd = group.Add(group.Add(a,b), group.Add(c,d));
|
||||
// But this should be fine:
|
||||
// abcd = group.Add(a, group.Add(b, group.Add(c,d));
|
||||
|
||||
// Abstract Group
|
||||
class TAOCRYPT_NO_VTABLE AbstractGroup : public virtual_base
|
||||
{
|
||||
public:
|
||||
typedef Integer Element;
|
||||
|
||||
virtual ~AbstractGroup() {}
|
||||
|
||||
virtual bool Equal(const Element &a, const Element &b) const =0;
|
||||
virtual const Element& Identity() const =0;
|
||||
virtual const Element& Add(const Element &a, const Element &b) const =0;
|
||||
virtual const Element& Inverse(const Element &a) const =0;
|
||||
virtual bool InversionIsFast() const {return false;}
|
||||
|
||||
virtual const Element& Double(const Element &a) const;
|
||||
virtual const Element& Subtract(const Element &a, const Element &b) const;
|
||||
virtual Element& Accumulate(Element &a, const Element &b) const;
|
||||
virtual Element& Reduce(Element &a, const Element &b) const;
|
||||
|
||||
virtual Element ScalarMultiply(const Element &a, const Integer &e) const;
|
||||
virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1,
|
||||
const Element &y, const Integer &e2) const;
|
||||
|
||||
virtual void SimultaneousMultiply(Element *results, const Element &base,
|
||||
const Integer *exponents, unsigned int exponentsCount) const;
|
||||
};
|
||||
|
||||
// Abstract Ring
|
||||
class TAOCRYPT_NO_VTABLE AbstractRing : public AbstractGroup
|
||||
{
|
||||
public:
|
||||
typedef Integer Element;
|
||||
|
||||
AbstractRing() : AbstractGroup() {m_mg.m_pRing = this;}
|
||||
AbstractRing(const AbstractRing &source) : AbstractGroup()
|
||||
{m_mg.m_pRing = this;}
|
||||
AbstractRing& operator=(const AbstractRing &source) {return *this;}
|
||||
|
||||
virtual bool IsUnit(const Element &a) const =0;
|
||||
virtual const Element& MultiplicativeIdentity() const =0;
|
||||
virtual const Element& Multiply(const Element&, const Element&) const =0;
|
||||
virtual const Element& MultiplicativeInverse(const Element &a) const =0;
|
||||
|
||||
virtual const Element& Square(const Element &a) const;
|
||||
virtual const Element& Divide(const Element &a, const Element &b) const;
|
||||
|
||||
virtual Element Exponentiate(const Element &a, const Integer &e) const;
|
||||
virtual Element CascadeExponentiate(const Element &x, const Integer &e1,
|
||||
const Element &y, const Integer &e2) const;
|
||||
|
||||
virtual void SimultaneousExponentiate(Element *results, const Element&,
|
||||
const Integer *exponents, unsigned int exponentsCount) const;
|
||||
|
||||
virtual const AbstractGroup& MultiplicativeGroup() const
|
||||
{return m_mg;}
|
||||
|
||||
private:
|
||||
class MultiplicativeGroupT : public AbstractGroup
|
||||
{
|
||||
public:
|
||||
const AbstractRing& GetRing() const
|
||||
{return *m_pRing;}
|
||||
|
||||
bool Equal(const Element &a, const Element &b) const
|
||||
{return GetRing().Equal(a, b);}
|
||||
|
||||
const Element& Identity() const
|
||||
{return GetRing().MultiplicativeIdentity();}
|
||||
|
||||
const Element& Add(const Element &a, const Element &b) const
|
||||
{return GetRing().Multiply(a, b);}
|
||||
|
||||
Element& Accumulate(Element &a, const Element &b) const
|
||||
{return a = GetRing().Multiply(a, b);}
|
||||
|
||||
const Element& Inverse(const Element &a) const
|
||||
{return GetRing().MultiplicativeInverse(a);}
|
||||
|
||||
const Element& Subtract(const Element &a, const Element &b) const
|
||||
{return GetRing().Divide(a, b);}
|
||||
|
||||
Element& Reduce(Element &a, const Element &b) const
|
||||
{return a = GetRing().Divide(a, b);}
|
||||
|
||||
const Element& Double(const Element &a) const
|
||||
{return GetRing().Square(a);}
|
||||
|
||||
Element ScalarMultiply(const Element &a, const Integer &e) const
|
||||
{return GetRing().Exponentiate(a, e);}
|
||||
|
||||
Element CascadeScalarMultiply(const Element &x, const Integer &e1,
|
||||
const Element &y, const Integer &e2) const
|
||||
{return GetRing().CascadeExponentiate(x, e1, y, e2);}
|
||||
|
||||
void SimultaneousMultiply(Element *results, const Element &base,
|
||||
const Integer *exponents, unsigned int exponentsCount) const
|
||||
{GetRing().SimultaneousExponentiate(results, base, exponents,
|
||||
exponentsCount);}
|
||||
|
||||
const AbstractRing* m_pRing;
|
||||
};
|
||||
|
||||
MultiplicativeGroupT m_mg;
|
||||
};
|
||||
|
||||
|
||||
// Abstract Euclidean Domain
|
||||
class TAOCRYPT_NO_VTABLE AbstractEuclideanDomain
|
||||
: public AbstractRing
|
||||
{
|
||||
public:
|
||||
typedef Integer Element;
|
||||
|
||||
virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a,
|
||||
const Element &d) const =0;
|
||||
|
||||
virtual const Element& Mod(const Element &a, const Element &b) const =0;
|
||||
virtual const Element& Gcd(const Element &a, const Element &b) const;
|
||||
|
||||
protected:
|
||||
mutable Element result;
|
||||
};
|
||||
|
||||
|
||||
// EuclideanDomainOf
|
||||
class EuclideanDomainOf : public AbstractEuclideanDomain
|
||||
{
|
||||
public:
|
||||
typedef Integer Element;
|
||||
|
||||
EuclideanDomainOf() {}
|
||||
|
||||
bool Equal(const Element &a, const Element &b) const
|
||||
{return a==b;}
|
||||
|
||||
const Element& Identity() const
|
||||
{return Element::Zero();}
|
||||
|
||||
const Element& Add(const Element &a, const Element &b) const
|
||||
{return result = a+b;}
|
||||
|
||||
Element& Accumulate(Element &a, const Element &b) const
|
||||
{return a+=b;}
|
||||
|
||||
const Element& Inverse(const Element &a) const
|
||||
{return result = -a;}
|
||||
|
||||
const Element& Subtract(const Element &a, const Element &b) const
|
||||
{return result = a-b;}
|
||||
|
||||
Element& Reduce(Element &a, const Element &b) const
|
||||
{return a-=b;}
|
||||
|
||||
const Element& Double(const Element &a) const
|
||||
{return result = a.Doubled();}
|
||||
|
||||
const Element& MultiplicativeIdentity() const
|
||||
{return Element::One();}
|
||||
|
||||
const Element& Multiply(const Element &a, const Element &b) const
|
||||
{return result = a*b;}
|
||||
|
||||
const Element& Square(const Element &a) const
|
||||
{return result = a.Squared();}
|
||||
|
||||
bool IsUnit(const Element &a) const
|
||||
{return a.IsUnit();}
|
||||
|
||||
const Element& MultiplicativeInverse(const Element &a) const
|
||||
{return result = a.MultiplicativeInverse();}
|
||||
|
||||
const Element& Divide(const Element &a, const Element &b) const
|
||||
{return result = a/b;}
|
||||
|
||||
const Element& Mod(const Element &a, const Element &b) const
|
||||
{return result = a%b;}
|
||||
|
||||
void DivisionAlgorithm(Element &r, Element &q, const Element &a,
|
||||
const Element &d) const
|
||||
{Element::Divide(r, q, a, d);}
|
||||
|
||||
private:
|
||||
mutable Element result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_ALGEBRA_HPP
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* arc4.hpp defines ARC4
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_ARC4_HPP
|
||||
#define TAO_CRYPT_ARC4_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// ARC4 encryption and decryption
|
||||
class ARC4 {
|
||||
public:
|
||||
enum { STATE_SIZE = 256 };
|
||||
|
||||
typedef ARC4 Encryption;
|
||||
typedef ARC4 Decryption;
|
||||
|
||||
ARC4() {}
|
||||
|
||||
void Process(byte*, const byte*, word32);
|
||||
void SetKey(const byte*, word32);
|
||||
private:
|
||||
byte x_;
|
||||
byte y_;
|
||||
byte state_[STATE_SIZE];
|
||||
|
||||
ARC4(const ARC4&); // hide copy
|
||||
const ARC4 operator=(const ARC4&); // and assign
|
||||
|
||||
void AsmProcess(byte*, const byte*, word32);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif // TAO_CRYPT_ARC4_HPP
|
||||
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* asn.hpp provides ASN1 BER, PublicKey, and x509v3 decoding
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_ASN_HPP
|
||||
#define TAO_CRYPT_ASN_HPP
|
||||
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "block.hpp"
|
||||
#include "error.hpp"
|
||||
#ifdef USE_SYS_STL
|
||||
#include <list>
|
||||
#else
|
||||
#include "list.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
// these tags and flags are not complete
|
||||
enum ASNTag
|
||||
{
|
||||
BOOLEAN = 0x01,
|
||||
INTEGER = 0x02,
|
||||
BIT_STRING = 0x03,
|
||||
OCTET_STRING = 0x04,
|
||||
TAG_NULL = 0x05,
|
||||
OBJECT_IDENTIFIER = 0x06,
|
||||
OBJECT_DESCRIPTOR = 0x07,
|
||||
EXTERNAL = 0x08,
|
||||
REAL = 0x09,
|
||||
ENUMERATED = 0x0a,
|
||||
UTF8_STRING = 0x0c,
|
||||
SEQUENCE = 0x10,
|
||||
SET = 0x11,
|
||||
NUMERIC_STRING = 0x12,
|
||||
PRINTABLE_STRING = 0x13,
|
||||
T61_STRING = 0x14,
|
||||
VIDEOTEXT_STRING = 0x15,
|
||||
IA5_STRING = 0x16,
|
||||
UTC_TIME = 0x17,
|
||||
GENERALIZED_TIME = 0x18,
|
||||
GRAPHIC_STRING = 0x19,
|
||||
VISIBLE_STRING = 0x1a,
|
||||
GENERAL_STRING = 0x1b,
|
||||
LONG_LENGTH = 0x80
|
||||
};
|
||||
|
||||
enum ASNIdFlag
|
||||
{
|
||||
UNIVERSAL = 0x00,
|
||||
DATA = 0x01,
|
||||
HEADER = 0x02,
|
||||
CONSTRUCTED = 0x20,
|
||||
APPLICATION = 0x40,
|
||||
CONTEXT_SPECIFIC = 0x80,
|
||||
PRIVATE = 0xc0
|
||||
};
|
||||
|
||||
|
||||
enum DNTags
|
||||
{
|
||||
COMMON_NAME = 0x03, // CN
|
||||
SUR_NAME = 0x04, // SN
|
||||
COUNTRY_NAME = 0x06, // C
|
||||
LOCALITY_NAME = 0x07, // L
|
||||
STATE_NAME = 0x08, // ST
|
||||
ORG_NAME = 0x0a, // O
|
||||
ORGUNIT_NAME = 0x0b // OU
|
||||
};
|
||||
|
||||
|
||||
enum PCKS12_Tags
|
||||
{
|
||||
/* DATA = 1, */ // from ASN1
|
||||
SIGNED_DATA = 2,
|
||||
ENVELOPED_DATA = 3,
|
||||
SIGNED_AND_ENVELOPED_DATA = 4,
|
||||
DIGESTED_DATA = 5,
|
||||
ENCRYPTED_DATA = 6
|
||||
};
|
||||
|
||||
|
||||
enum Constants
|
||||
{
|
||||
MIN_DATE_SZ = 13,
|
||||
MAX_DATE_SZ = 16,
|
||||
MAX_ALGO_SZ = 16,
|
||||
MAX_LENGTH_SZ = 5,
|
||||
MAX_SEQ_SZ = 5, // enum(seq|con) + length(4)
|
||||
MAX_ALGO_SIZE = 9,
|
||||
MAX_DIGEST_SZ = 25, // SHA + enum(Bit or Octet) + length(4)
|
||||
DSA_SIG_SZ = 40,
|
||||
ASN_NAME_MAX = 512 // max total of all included names
|
||||
};
|
||||
|
||||
|
||||
class Source;
|
||||
class RSA_PublicKey;
|
||||
class RSA_PrivateKey;
|
||||
class DSA_PublicKey;
|
||||
class DSA_PrivateKey;
|
||||
class Integer;
|
||||
class DH;
|
||||
|
||||
|
||||
// General BER decoding
|
||||
class BER_Decoder : public virtual_base {
|
||||
protected:
|
||||
Source& source_;
|
||||
public:
|
||||
explicit BER_Decoder(Source& s) : source_(s) {}
|
||||
virtual ~BER_Decoder() {}
|
||||
|
||||
Integer& GetInteger(Integer&);
|
||||
word32 GetSequence();
|
||||
word32 GetSet();
|
||||
word32 GetVersion();
|
||||
word32 GetExplicitVersion();
|
||||
|
||||
Error GetError();
|
||||
private:
|
||||
virtual void ReadHeader() = 0;
|
||||
|
||||
BER_Decoder(const BER_Decoder&); // hide copy
|
||||
BER_Decoder& operator=(const BER_Decoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// RSA Private Key BER Decoder
|
||||
class RSA_Private_Decoder : public BER_Decoder {
|
||||
public:
|
||||
explicit RSA_Private_Decoder(Source& s) : BER_Decoder(s) {}
|
||||
void Decode(RSA_PrivateKey&);
|
||||
private:
|
||||
void ReadHeader();
|
||||
};
|
||||
|
||||
|
||||
// RSA Public Key BER Decoder
|
||||
class RSA_Public_Decoder : public BER_Decoder {
|
||||
public:
|
||||
explicit RSA_Public_Decoder(Source& s) : BER_Decoder(s) {}
|
||||
void Decode(RSA_PublicKey&);
|
||||
private:
|
||||
void ReadHeader();
|
||||
};
|
||||
|
||||
|
||||
// DSA Private Key BER Decoder
|
||||
class DSA_Private_Decoder : public BER_Decoder {
|
||||
public:
|
||||
explicit DSA_Private_Decoder(Source& s) : BER_Decoder(s) {}
|
||||
void Decode(DSA_PrivateKey&);
|
||||
private:
|
||||
void ReadHeader();
|
||||
};
|
||||
|
||||
|
||||
// DSA Public Key BER Decoder
|
||||
class DSA_Public_Decoder : public BER_Decoder {
|
||||
public:
|
||||
explicit DSA_Public_Decoder(Source& s) : BER_Decoder(s) {}
|
||||
void Decode(DSA_PublicKey&);
|
||||
private:
|
||||
void ReadHeader();
|
||||
};
|
||||
|
||||
|
||||
// DH Key BER Decoder
|
||||
class DH_Decoder : public BER_Decoder {
|
||||
public:
|
||||
explicit DH_Decoder(Source& s) : BER_Decoder(s) {}
|
||||
void Decode(DH&);
|
||||
private:
|
||||
void ReadHeader();
|
||||
};
|
||||
|
||||
|
||||
// PKCS12 BER Decoder
|
||||
class PKCS12_Decoder : public BER_Decoder {
|
||||
public:
|
||||
explicit PKCS12_Decoder(Source& s) : BER_Decoder(s) {}
|
||||
void Decode();
|
||||
private:
|
||||
void ReadHeader();
|
||||
};
|
||||
|
||||
|
||||
// General PublicKey
|
||||
class PublicKey {
|
||||
byte* key_;
|
||||
word32 sz_;
|
||||
public:
|
||||
explicit PublicKey(const byte* k = 0, word32 s = 0);
|
||||
~PublicKey() { tcArrayDelete(key_); }
|
||||
|
||||
const byte* GetKey() const { return key_; }
|
||||
word32 size() const { return sz_; }
|
||||
|
||||
void SetKey(const byte*);
|
||||
void SetSize(word32 s);
|
||||
|
||||
void AddToEnd(const byte*, word32);
|
||||
private:
|
||||
PublicKey(const PublicKey&); // hide copy
|
||||
PublicKey& operator=(const PublicKey&); // and assign
|
||||
};
|
||||
|
||||
|
||||
enum { SHA_SIZE = 20 };
|
||||
|
||||
|
||||
// A Signing Authority
|
||||
class Signer {
|
||||
PublicKey key_;
|
||||
char name_[ASN_NAME_MAX];
|
||||
byte hash_[SHA_SIZE];
|
||||
public:
|
||||
Signer(const byte* k, word32 kSz, const char* n, const byte* h);
|
||||
~Signer();
|
||||
|
||||
const PublicKey& GetPublicKey() const { return key_; }
|
||||
const char* GetName() const { return name_; }
|
||||
const byte* GetHash() const { return hash_; }
|
||||
|
||||
private:
|
||||
Signer(const Signer&); // hide copy
|
||||
Signer& operator=(const Signer&); // and assign
|
||||
};
|
||||
|
||||
|
||||
typedef STL::list<Signer*> SignerList;
|
||||
|
||||
|
||||
enum ContentType { HUH = 651 };
|
||||
enum SigType { SHAwDSA = 517, MD2wRSA = 646, MD5wRSA = 648, SHAwRSA =649};
|
||||
enum HashType { MD2h = 646, MD5h = 649, SHAh = 88 };
|
||||
enum KeyType { DSAk = 515, RSAk = 645 }; // sums of algo OID
|
||||
|
||||
|
||||
// an x509v Certificate BER Decoder
|
||||
class CertDecoder : public BER_Decoder {
|
||||
public:
|
||||
enum DateType { BEFORE, AFTER };
|
||||
enum NameType { ISSUER, SUBJECT };
|
||||
enum CertType { CA, USER };
|
||||
|
||||
explicit CertDecoder(Source&, bool decode = true, SignerList* sl = 0,
|
||||
bool noVerify = false, CertType ct = USER);
|
||||
~CertDecoder();
|
||||
|
||||
const PublicKey& GetPublicKey() const { return key_; }
|
||||
KeyType GetKeyType() const { return KeyType(keyOID_); }
|
||||
const char* GetIssuer() const { return issuer_; }
|
||||
const char* GetCommonName() const { return subject_; }
|
||||
const byte* GetHash() const { return subjectHash_; }
|
||||
const char* GetBeforeDate() const { return beforeDate_; }
|
||||
const char* GetAfterDate() const { return afterDate_; }
|
||||
|
||||
void DecodeToKey();
|
||||
private:
|
||||
PublicKey key_;
|
||||
word32 certBegin_; // offset to start of cert
|
||||
word32 sigIndex_; // offset to start of signature
|
||||
word32 sigLength_; // length of signature
|
||||
word32 signatureOID_; // sum of algorithm object id
|
||||
word32 keyOID_; // sum of key algo object id
|
||||
byte subjectHash_[SHA_SIZE]; // hash of all Names
|
||||
byte issuerHash_[SHA_SIZE]; // hash of all Names
|
||||
byte* signature_;
|
||||
char issuer_[ASN_NAME_MAX]; // Names
|
||||
char subject_[ASN_NAME_MAX]; // Names
|
||||
char beforeDate_[MAX_DATE_SZ]; // valid before date
|
||||
char afterDate_[MAX_DATE_SZ]; // valid after date
|
||||
bool verify_; // Default to yes, but could be off
|
||||
|
||||
void ReadHeader();
|
||||
void Decode(SignerList*, CertType);
|
||||
void StoreKey();
|
||||
void AddDSA();
|
||||
bool ValidateSelfSignature();
|
||||
bool ValidateSignature(SignerList*);
|
||||
bool ConfirmSignature(Source&);
|
||||
void GetKey();
|
||||
void GetName(NameType);
|
||||
void GetValidity();
|
||||
void GetDate(DateType);
|
||||
void GetCompareHash(const byte*, word32, byte*, word32);
|
||||
word32 GetAlgoId();
|
||||
word32 GetSignature();
|
||||
word32 GetDigest();
|
||||
};
|
||||
|
||||
|
||||
word32 GetLength(Source&);
|
||||
|
||||
word32 SetLength(word32, byte*);
|
||||
word32 SetSequence(word32, byte*);
|
||||
|
||||
word32 EncodeDSA_Signature(const byte* signature, byte* output);
|
||||
word32 EncodeDSA_Signature(const Integer& r, const Integer& s, byte* output);
|
||||
word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz);
|
||||
|
||||
|
||||
// General DER encoding
|
||||
class DER_Encoder : public virtual_base {
|
||||
public:
|
||||
DER_Encoder() {}
|
||||
virtual ~DER_Encoder() {}
|
||||
|
||||
word32 SetAlgoID(HashType, byte*);
|
||||
|
||||
Error GetError() const { return error_; }
|
||||
private:
|
||||
//virtual void WriteHeader() = 0;
|
||||
Error error_;
|
||||
|
||||
DER_Encoder(const DER_Encoder&); // hide copy
|
||||
DER_Encoder& operator=(const DER_Encoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Signature_Encoder : public DER_Encoder {
|
||||
const byte* digest_;
|
||||
word32 digestSz_;
|
||||
SigType digestOID_;
|
||||
public:
|
||||
explicit Signature_Encoder(const byte*, word32, HashType, Source&);
|
||||
|
||||
private:
|
||||
void WriteHeader();
|
||||
word32 SetDigest(const byte*, word32, byte*);
|
||||
|
||||
Signature_Encoder(const Signature_Encoder&); // hide copy
|
||||
Signature_Encoder& operator=(const Signature_Encoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// Get Cert in PEM format from BEGIN to END
|
||||
int GetCert(Source&);
|
||||
|
||||
// Get Cert in PEM format from pkcs12 file
|
||||
int GetPKCS_Cert(const char* password, Source&);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif // TAO_CRYPT_ASN_HPP
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* block.hpp provides word and byte blocks with configurable allocators
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_BLOCK_HPP
|
||||
#define TAO_CRYPT_BLOCK_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include <string.h> // memcpy
|
||||
#include <stddef.h> // ptrdiff_t
|
||||
|
||||
#ifdef USE_SYS_STL
|
||||
#include <algorithm>
|
||||
#else
|
||||
#include "algorithm.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// a Base class for Allocators
|
||||
template<class T>
|
||||
class AllocatorBase
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
|
||||
pointer address(reference r) const {return (&r);}
|
||||
const_pointer address(const_reference r) const {return (&r); }
|
||||
void construct(pointer p, const T& val) {new (p) T(val);}
|
||||
void destroy(pointer p) {p->~T();}
|
||||
size_type max_size() const {return ~size_type(0)/sizeof(T);}
|
||||
protected:
|
||||
static void CheckSize(size_t n)
|
||||
{
|
||||
assert(n <= ~size_t(0) / sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// General purpose realloc
|
||||
template<typename T, class A>
|
||||
typename A::pointer StdReallocate(A& a, T* p, typename A::size_type oldSize,
|
||||
typename A::size_type newSize, bool preserve)
|
||||
{
|
||||
if (oldSize == newSize)
|
||||
return p;
|
||||
|
||||
if (preserve) {
|
||||
A b = A();
|
||||
typename A::pointer newPointer = b.allocate(newSize, 0);
|
||||
memcpy(newPointer, p, sizeof(T) * min(oldSize, newSize));
|
||||
a.deallocate(p, oldSize);
|
||||
STL::swap(a, b);
|
||||
return newPointer;
|
||||
}
|
||||
else {
|
||||
a.deallocate(p, oldSize);
|
||||
return a.allocate(newSize, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Allocator that zeros out memory on deletion
|
||||
template <class T>
|
||||
class AllocatorWithCleanup : public AllocatorBase<T>
|
||||
{
|
||||
public:
|
||||
typedef typename AllocatorBase<T>::pointer pointer;
|
||||
typedef typename AllocatorBase<T>::size_type size_type;
|
||||
|
||||
pointer allocate(size_type n, const void* = 0)
|
||||
{
|
||||
this->CheckSize(n);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
return NEW_TC T[n];
|
||||
}
|
||||
|
||||
void deallocate(void* p, size_type n)
|
||||
{
|
||||
memset(p, 0, n * sizeof(T));
|
||||
tcArrayDelete((T*)p);
|
||||
}
|
||||
|
||||
pointer reallocate(T* p, size_type oldSize, size_type newSize,
|
||||
bool preserve)
|
||||
{
|
||||
return StdReallocate(*this, p, oldSize, newSize, preserve);
|
||||
}
|
||||
|
||||
// VS.NET STL enforces the policy of "All STL-compliant allocators have to
|
||||
// provide a template class member called rebind".
|
||||
template <class U> struct rebind { typedef AllocatorWithCleanup<U> other;};
|
||||
};
|
||||
|
||||
|
||||
// Block class template
|
||||
template<typename T, class A = AllocatorWithCleanup<T> >
|
||||
class Block {
|
||||
public:
|
||||
explicit Block(word32 s = 0) : sz_(s), buffer_(allocator_.allocate(sz_))
|
||||
{ CleanNew(sz_); }
|
||||
|
||||
Block(const T* buff, word32 s) : sz_(s), buffer_(allocator_.allocate(sz_))
|
||||
{ memcpy(buffer_, buff, sz_ * sizeof(T)); }
|
||||
|
||||
Block(const Block& that) : sz_(that.sz_), buffer_(allocator_.allocate(sz_))
|
||||
{ memcpy(buffer_, that.buffer_, sz_ * sizeof(T)); }
|
||||
|
||||
Block& operator=(const Block& that) {
|
||||
Block tmp(that);
|
||||
Swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator[] (word32 i) { assert(i < sz_); return buffer_[i]; }
|
||||
const T& operator[] (word32 i) const
|
||||
{ assert(i < sz_); return buffer_[i]; }
|
||||
|
||||
T* operator+ (word32 i) { return buffer_ + i; }
|
||||
const T* operator+ (word32 i) const { return buffer_ + i; }
|
||||
|
||||
word32 size() const { return sz_; }
|
||||
|
||||
T* get_buffer() const { return buffer_; }
|
||||
T* begin() const { return get_buffer(); }
|
||||
|
||||
void CleanGrow(word32 newSize)
|
||||
{
|
||||
if (newSize > sz_) {
|
||||
buffer_ = allocator_.reallocate(buffer_, sz_, newSize, true);
|
||||
memset(buffer_ + sz_, 0, (newSize - sz_) * sizeof(T));
|
||||
sz_ = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
void CleanNew(word32 newSize)
|
||||
{
|
||||
New(newSize);
|
||||
memset(buffer_, 0, sz_ * sizeof(T));
|
||||
}
|
||||
|
||||
void New(word32 newSize)
|
||||
{
|
||||
buffer_ = allocator_.reallocate(buffer_, sz_, newSize, false);
|
||||
sz_ = newSize;
|
||||
}
|
||||
|
||||
void resize(word32 newSize)
|
||||
{
|
||||
buffer_ = allocator_.reallocate(buffer_, sz_, newSize, true);
|
||||
sz_ = newSize;
|
||||
}
|
||||
|
||||
void Swap(Block& other) {
|
||||
STL::swap(sz_, other.sz_);
|
||||
STL::swap(buffer_, other.buffer_);
|
||||
STL::swap(allocator_, other.allocator_);
|
||||
}
|
||||
|
||||
~Block() { allocator_.deallocate(buffer_, sz_); }
|
||||
private:
|
||||
word32 sz_; // size in Ts
|
||||
T* buffer_;
|
||||
A allocator_;
|
||||
};
|
||||
|
||||
|
||||
typedef Block<byte> ByteBlock;
|
||||
typedef Block<word> WordBlock;
|
||||
typedef Block<word32> Word32Block;
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_BLOCK_HPP
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* blowfish.hpp defines Blowfish
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_BLOWFISH_HPP
|
||||
#define TAO_CRYPT_BLOWFISH_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "modes.hpp"
|
||||
#ifdef USE_SYS_STL
|
||||
#include <algorithm>
|
||||
#else
|
||||
#include "algorithm.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace STL = STL_NAMESPACE;
|
||||
|
||||
|
||||
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
|
||||
#define DO_BLOWFISH_ASM
|
||||
#endif
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
enum { BLOWFISH_BLOCK_SIZE = 8 };
|
||||
|
||||
|
||||
// Blowfish encryption and decryption, see
|
||||
class Blowfish : public Mode_BASE {
|
||||
public:
|
||||
enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 };
|
||||
|
||||
Blowfish(CipherDir DIR, Mode MODE)
|
||||
: Mode_BASE(BLOCK_SIZE, DIR, MODE) {}
|
||||
|
||||
#ifdef DO_BLOWFISH_ASM
|
||||
void Process(byte*, const byte*, word32);
|
||||
#endif
|
||||
void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
|
||||
void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
|
||||
private:
|
||||
static const word32 p_init_[ROUNDS + 2];
|
||||
static const word32 s_init_[4 * 256];
|
||||
|
||||
word32 pbox_[ROUNDS + 2];
|
||||
word32 sbox_[4 * 256];
|
||||
|
||||
void crypt_block(const word32 in[2], word32 out[2]) const;
|
||||
void AsmProcess(const byte* in, byte* out) const;
|
||||
void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
|
||||
|
||||
Blowfish(const Blowfish&); // hide copy
|
||||
Blowfish& operator=(const Blowfish&); // and assign
|
||||
};
|
||||
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, Blowfish, ECB> Blowfish_ECB_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, Blowfish, ECB> Blowfish_ECB_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, Blowfish, CBC> Blowfish_CBC_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, Blowfish, CBC> Blowfish_CBC_Decryption;
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_BLOWFISH_HPP
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* coding.hpp defines hex and base64 encoding/decoing
|
||||
*/
|
||||
|
||||
#ifndef TAO_CRYPT_CODING_HPP
|
||||
#define TAO_CRYPT_CODING_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "block.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
class Source;
|
||||
|
||||
|
||||
// Hex Encoding, see RFC 3548
|
||||
class HexEncoder {
|
||||
ByteBlock encoded_;
|
||||
Source& plain_;
|
||||
public:
|
||||
explicit HexEncoder(Source& s) : plain_(s) { Encode(); }
|
||||
private:
|
||||
void Encode();
|
||||
|
||||
HexEncoder(const HexEncoder&); // hide copy
|
||||
HexEncoder& operator=(const HexEncoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// Hex Decoding, see RFC 3548
|
||||
class HexDecoder {
|
||||
ByteBlock decoded_;
|
||||
Source& coded_;
|
||||
public:
|
||||
explicit HexDecoder(Source& s) : coded_(s) { Decode(); }
|
||||
private:
|
||||
void Decode();
|
||||
|
||||
HexDecoder(const HexDecoder&); // hide copy
|
||||
HexDecoder& operator=(const HexDecoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// Base 64 encoding, see RFC 3548
|
||||
class Base64Encoder {
|
||||
ByteBlock encoded_;
|
||||
Source& plain_;
|
||||
public:
|
||||
explicit Base64Encoder(Source& s) : plain_(s) { Encode(); }
|
||||
private:
|
||||
void Encode();
|
||||
|
||||
Base64Encoder(const Base64Encoder&); // hide copy
|
||||
Base64Encoder& operator=(const Base64Encoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// Base 64 decoding, see RFC 3548
|
||||
class Base64Decoder {
|
||||
ByteBlock decoded_;
|
||||
Source& coded_;
|
||||
public:
|
||||
explicit Base64Decoder(Source& s) : coded_(s) { Decode(); }
|
||||
private:
|
||||
void Decode();
|
||||
|
||||
Base64Decoder(const Base64Decoder&); // hide copy
|
||||
Base64Decoder& operator=(const Base64Decoder&); // and assign
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_CODING_HPP
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* des.hpp defines DES, DES_EDE2, and DES_EDE3
|
||||
see FIPS 46-2 and FIPS 81
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_DES_HPP
|
||||
#define TAO_CRYPT_DES_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "modes.hpp"
|
||||
|
||||
|
||||
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
|
||||
#define DO_DES_ASM
|
||||
#endif
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
enum { DES_BLOCK_SIZE = 8, DES_KEY_SIZE = 32 };
|
||||
|
||||
|
||||
class BasicDES {
|
||||
public:
|
||||
void SetKey(const byte*, word32, CipherDir dir);
|
||||
void RawProcessBlock(word32&, word32&) const;
|
||||
protected:
|
||||
word32 k_[DES_KEY_SIZE];
|
||||
};
|
||||
|
||||
|
||||
// DES
|
||||
class DES : public Mode_BASE, public BasicDES {
|
||||
public:
|
||||
DES(CipherDir DIR, Mode MODE)
|
||||
: Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {}
|
||||
|
||||
private:
|
||||
void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
|
||||
|
||||
DES(const DES&); // hide copy
|
||||
DES& operator=(const DES&); // and assign
|
||||
};
|
||||
|
||||
|
||||
// DES_EDE2
|
||||
class DES_EDE2 : public Mode_BASE {
|
||||
public:
|
||||
DES_EDE2(CipherDir DIR, Mode MODE)
|
||||
: Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {}
|
||||
|
||||
void SetKey(const byte*, word32, CipherDir dir);
|
||||
private:
|
||||
BasicDES des1_;
|
||||
BasicDES des2_;
|
||||
|
||||
void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
|
||||
|
||||
DES_EDE2(const DES_EDE2&); // hide copy
|
||||
DES_EDE2& operator=(const DES_EDE2&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
// DES_EDE3
|
||||
class DES_EDE3 : public Mode_BASE {
|
||||
public:
|
||||
DES_EDE3(CipherDir DIR, Mode MODE)
|
||||
: Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {}
|
||||
|
||||
void SetKey(const byte*, word32, CipherDir dir);
|
||||
void SetIV(const byte* iv) { memcpy(r_, iv, DES_BLOCK_SIZE); }
|
||||
#ifdef DO_DES_ASM
|
||||
void Process(byte*, const byte*, word32);
|
||||
#endif
|
||||
private:
|
||||
BasicDES des1_;
|
||||
BasicDES des2_;
|
||||
BasicDES des3_;
|
||||
|
||||
void AsmProcess(const byte* in, byte* out, void* box) const;
|
||||
void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
|
||||
|
||||
DES_EDE3(const DES_EDE3&); // hide copy
|
||||
DES_EDE3& operator=(const DES_EDE3&); // and assign
|
||||
};
|
||||
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, DES, ECB> DES_ECB_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, DES, ECB> DES_ECB_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, DES, CBC> DES_CBC_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, DES, CBC> DES_CBC_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, DES_EDE2, ECB> DES_EDE2_ECB_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, DES_EDE2, ECB> DES_EDE2_ECB_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, DES_EDE2, CBC> DES_EDE2_CBC_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, DES_EDE2, CBC> DES_EDE2_CBC_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, DES_EDE3, ECB> DES_EDE3_ECB_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, DES_EDE3, ECB> DES_EDE3_ECB_Decryption;
|
||||
|
||||
typedef BlockCipher<ENCRYPTION, DES_EDE3, CBC> DES_EDE3_CBC_Encryption;
|
||||
typedef BlockCipher<DECRYPTION, DES_EDE3, CBC> DES_EDE3_CBC_Decryption;
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif // TAO_CRYPT_DES_HPP
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* dh.hpp provides Diffie-Hellman support
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_DH_HPP
|
||||
#define TAO_CRYPT_DH_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "integer.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
class Source;
|
||||
|
||||
|
||||
// Diffie-Hellman
|
||||
class DH {
|
||||
public:
|
||||
DH() {}
|
||||
DH(Integer& p, Integer& g) : p_(p), g_(g) {}
|
||||
explicit DH(Source&);
|
||||
|
||||
DH(const DH& that) : p_(that.p_), g_(that.g_) {}
|
||||
DH& operator=(const DH& that)
|
||||
{
|
||||
DH tmp(that);
|
||||
Swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Swap(DH& other)
|
||||
{
|
||||
p_.Swap(other.p_);
|
||||
g_.Swap(other.g_);
|
||||
}
|
||||
|
||||
void Initialize(Source&);
|
||||
void Initialize(Integer& p, Integer& g)
|
||||
{
|
||||
SetP(p);
|
||||
SetG(g);
|
||||
}
|
||||
|
||||
void GenerateKeyPair(RandomNumberGenerator&, byte*, byte*);
|
||||
void Agree(byte*, const byte*, const byte*, word32 otherSz = 0);
|
||||
|
||||
void SetP(const Integer& p) { p_ = p; }
|
||||
void SetG(const Integer& g) { g_ = g; }
|
||||
|
||||
Integer& GetP() { return p_; }
|
||||
Integer& GetG() { return g_; }
|
||||
|
||||
// for p and agree
|
||||
word32 GetByteLength() const { return p_.ByteCount(); }
|
||||
private:
|
||||
// group parms
|
||||
Integer p_;
|
||||
Integer g_;
|
||||
|
||||
void GeneratePrivate(RandomNumberGenerator&, byte*);
|
||||
void GeneratePublic(const byte*, byte*);
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_DH_HPP
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* dsa.hpp provides Digitial Signautre Algorithm see FIPS 186-2
|
||||
*/
|
||||
|
||||
#ifndef TAO_CRYPT_DSA_HPP
|
||||
#define TAO_CRYPT_DSA_HPP
|
||||
|
||||
#include "integer.hpp"
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
class Source;
|
||||
|
||||
|
||||
class DSA_PublicKey {
|
||||
protected:
|
||||
Integer p_;
|
||||
Integer q_;
|
||||
Integer g_;
|
||||
Integer y_;
|
||||
public:
|
||||
DSA_PublicKey() {}
|
||||
explicit DSA_PublicKey(Source&);
|
||||
|
||||
void Initialize(Source&);
|
||||
void Initialize(const Integer& p, const Integer& q, const Integer& g,
|
||||
const Integer& y);
|
||||
|
||||
const Integer& GetModulus() const;
|
||||
const Integer& GetSubGroupOrder() const;
|
||||
const Integer& GetSubGroupGenerator() const;
|
||||
const Integer& GetPublicPart() const;
|
||||
|
||||
void SetModulus(const Integer&);
|
||||
void SetSubGroupOrder(const Integer&);
|
||||
void SetSubGroupGenerator(const Integer&);
|
||||
void SetPublicPart(const Integer&);
|
||||
|
||||
word32 SignatureLength() const;
|
||||
|
||||
DSA_PublicKey(const DSA_PublicKey&);
|
||||
DSA_PublicKey& operator=(const DSA_PublicKey&);
|
||||
|
||||
void Swap(DSA_PublicKey& other);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DSA_PrivateKey : public DSA_PublicKey {
|
||||
Integer x_;
|
||||
public:
|
||||
DSA_PrivateKey() {}
|
||||
explicit DSA_PrivateKey(Source&);
|
||||
|
||||
void Initialize(Source&);
|
||||
void Initialize(const Integer& p, const Integer& q, const Integer& g,
|
||||
const Integer& y, const Integer& x);
|
||||
|
||||
const Integer& GetPrivatePart() const;
|
||||
|
||||
void SetPrivatePart(const Integer&);
|
||||
private:
|
||||
DSA_PrivateKey(const DSA_PrivateKey&); // hide copy
|
||||
DSA_PrivateKey& operator=(const DSA_PrivateKey&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
class DSA_Signer {
|
||||
const DSA_PrivateKey& key_;
|
||||
Integer r_;
|
||||
Integer s_;
|
||||
public:
|
||||
explicit DSA_Signer(const DSA_PrivateKey&);
|
||||
|
||||
word32 Sign(const byte* sha_digest, byte* sig, RandomNumberGenerator&);
|
||||
|
||||
const Integer& GetR() const;
|
||||
const Integer& GetS() const;
|
||||
private:
|
||||
DSA_Signer(const DSA_Signer&); // hide copy
|
||||
DSA_Signer& operator=(DSA_Signer&); // and assign
|
||||
};
|
||||
|
||||
|
||||
class DSA_Verifier {
|
||||
const DSA_PublicKey& key_;
|
||||
Integer r_;
|
||||
Integer s_;
|
||||
public:
|
||||
explicit DSA_Verifier(const DSA_PublicKey&);
|
||||
|
||||
bool Verify(const byte* sha_digest, const byte* sig);
|
||||
|
||||
const Integer& GetR() const;
|
||||
const Integer& GetS() const;
|
||||
private:
|
||||
DSA_Verifier(const DSA_Verifier&); // hide copy
|
||||
DSA_Verifier& operator=(const DSA_Verifier&); // and assign
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_DSA_HPP
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* error.hpp provides a taocrypt error numbers
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_ERROR_HPP
|
||||
#define TAO_CRYPT_ERROR_HPP
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
enum ErrorNumber {
|
||||
|
||||
NO_ERROR_E = 0, // "not in error state"
|
||||
|
||||
// RandomNumberGenerator
|
||||
WINCRYPT_E = 1001, // "bad wincrypt acquire"
|
||||
CRYPTGEN_E = 1002, // "CryptGenRandom error"
|
||||
OPEN_RAN_E = 1003, // "open /dev/urandom error"
|
||||
READ_RAN_E = 1004, // "read /dev/urandom error"
|
||||
|
||||
// Integer
|
||||
INTEGER_E = 1010, // "bad DER Integer Header"
|
||||
|
||||
|
||||
// ASN.1
|
||||
SEQUENCE_E = 1020, // "bad Sequence Header"
|
||||
SET_E = 1021, // "bad Set Header"
|
||||
VERSION_E = 1022, // "version length not 1"
|
||||
SIG_OID_E = 1023, // "signature OID mismatch"
|
||||
BIT_STR_E = 1024, // "bad BitString Header"
|
||||
UNKNOWN_OID_E = 1025, // "unknown key OID type"
|
||||
OBJECT_ID_E = 1026, // "bad Ojbect ID Header"
|
||||
TAG_NULL_E = 1027, // "expected TAG NULL"
|
||||
EXPECT_0_E = 1028, // "expected 0"
|
||||
OCTET_STR_E = 1029, // "bad Octet String Header"
|
||||
TIME_E = 1030, // "bad TIME"
|
||||
|
||||
DATE_SZ_E = 1031, // "bad Date Size"
|
||||
SIG_LEN_E = 1032, // "bad Signature Length"
|
||||
UNKOWN_SIG_E = 1033, // "unknown signature OID"
|
||||
UNKOWN_HASH_E = 1034, // "unknown hash OID"
|
||||
DSA_SZ_E = 1035, // "bad DSA r or s size"
|
||||
BEFORE_DATE_E = 1036, // "before date in the future"
|
||||
AFTER_DATE_E = 1037, // "after date in the past"
|
||||
SIG_CONFIRM_E = 1038, // "bad self signature confirmation"
|
||||
SIG_OTHER_E = 1039, // "bad other signature confirmation"
|
||||
|
||||
CONTENT_E = 1040, // "bad content processing"
|
||||
PEM_E = 1041 // "bad pem format error"
|
||||
|
||||
// add error string to yassl/src/yassl_error.cpp !!!
|
||||
};
|
||||
|
||||
|
||||
struct Error {
|
||||
ErrorNumber what_; // description number, 0 for no error
|
||||
|
||||
explicit Error(ErrorNumber w = NO_ERROR_E) : what_(w) {}
|
||||
|
||||
ErrorNumber What() const { return what_; }
|
||||
void SetError(ErrorNumber w) { what_ = w; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace TaoCrypt
|
||||
|
||||
#endif // TAO_CRYPT_ERROR_HPP
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* file.hpp provies File Sources and Sinks
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_FILE_HPP
|
||||
#define TAO_CRYPT_FILE_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "block.hpp"
|
||||
#include "error.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
class Source {
|
||||
ByteBlock buffer_;
|
||||
word32 current_;
|
||||
Error error_;
|
||||
public:
|
||||
explicit Source(word32 sz = 0) : buffer_(sz), current_(0) {}
|
||||
Source(const byte* b, word32 sz) : buffer_(b, sz), current_(0) {}
|
||||
|
||||
word32 size() const { return buffer_.size(); }
|
||||
void grow(word32 sz) { buffer_.CleanGrow(sz); }
|
||||
|
||||
const byte* get_buffer() const { return buffer_.get_buffer(); }
|
||||
const byte* get_current() const { return &buffer_[current_]; }
|
||||
word32 get_index() const { return current_; }
|
||||
void set_index(word32 i) { current_ = i; }
|
||||
|
||||
byte operator[] (word32 i) { current_ = i; return next(); }
|
||||
byte next() { return buffer_[current_++]; }
|
||||
byte prev() { return buffer_[--current_]; }
|
||||
|
||||
void add(const byte* data, word32 len)
|
||||
{
|
||||
memcpy(buffer_.get_buffer() + current_, data, len);
|
||||
current_ += len;
|
||||
}
|
||||
|
||||
void advance(word32 i) { current_ += i; }
|
||||
void reset(ByteBlock&);
|
||||
|
||||
Error GetError() { return error_; }
|
||||
void SetError(ErrorNumber w) { error_.SetError(w); }
|
||||
|
||||
friend class FileSource; // for get()
|
||||
|
||||
Source(const Source& that)
|
||||
: buffer_(that.buffer_), current_(that.current_) {}
|
||||
|
||||
Source& operator=(const Source& that)
|
||||
{
|
||||
Source tmp(that);
|
||||
Swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Swap(Source& other)
|
||||
{
|
||||
buffer_.Swap(other.buffer_);
|
||||
STL::swap(current_, other.current_);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// File Source
|
||||
class FileSource {
|
||||
FILE* file_;
|
||||
public:
|
||||
FileSource(const char* fname, Source& source);
|
||||
~FileSource();
|
||||
|
||||
word32 size(bool use_current = false);
|
||||
private:
|
||||
word32 get(Source&);
|
||||
word32 size_left();
|
||||
|
||||
FileSource(const FileSource&); // hide
|
||||
FileSource& operator=(const FileSource&); // hide
|
||||
};
|
||||
|
||||
|
||||
// File Sink
|
||||
class FileSink {
|
||||
FILE* file_;
|
||||
public:
|
||||
FileSink(const char* fname, Source& source);
|
||||
~FileSink();
|
||||
|
||||
word32 size(bool use_current = false);
|
||||
private:
|
||||
void put(Source&);
|
||||
|
||||
FileSink(const FileSink&); // hide
|
||||
FileSink& operator=(const FileSink&); // hide
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_FILE_HPP
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* hash.hpp provides a base for digest types
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_HASH_HPP
|
||||
#define TAO_CRYPT_HASH_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// HASH
|
||||
class HASH : public virtual_base {
|
||||
public:
|
||||
virtual ~HASH() {}
|
||||
|
||||
virtual void Update(const byte*, word32) = 0;
|
||||
virtual void Final(byte*) = 0;
|
||||
|
||||
virtual void Init() = 0;
|
||||
|
||||
virtual word32 getBlockSize() const = 0;
|
||||
virtual word32 getDigestSize() const = 0;
|
||||
};
|
||||
|
||||
|
||||
// HASH with Transform
|
||||
class HASHwithTransform : public HASH {
|
||||
public:
|
||||
HASHwithTransform(word32 digSz, word32 buffSz);
|
||||
virtual ~HASHwithTransform() {}
|
||||
virtual ByteOrder getByteOrder() const = 0;
|
||||
virtual word32 getPadSize() const = 0;
|
||||
|
||||
virtual void Update(const byte*, word32);
|
||||
virtual void Final(byte*);
|
||||
|
||||
word32 GetBitCountLo() const { return loLen_ << 3; }
|
||||
word32 GetBitCountHi() const { return (loLen_ >> (8*sizeof(loLen_) - 3)) +
|
||||
(hiLen_ << 3); }
|
||||
enum { MaxDigestSz = 8, MaxBufferSz = 64 };
|
||||
protected:
|
||||
typedef word32 HashLengthType;
|
||||
word32 buffLen_; // in bytes
|
||||
HashLengthType loLen_; // length in bytes
|
||||
HashLengthType hiLen_; // length in bytes
|
||||
word32 digest_[MaxDigestSz];
|
||||
word32 buffer_[MaxBufferSz / sizeof(word32)];
|
||||
|
||||
virtual void Transform() = 0;
|
||||
|
||||
void AddLength(word32);
|
||||
};
|
||||
|
||||
|
||||
#ifdef WORD64_AVAILABLE
|
||||
|
||||
// 64-bit HASH with Transform
|
||||
class HASH64withTransform : public HASH {
|
||||
public:
|
||||
HASH64withTransform(word32 digSz, word32 buffSz);
|
||||
virtual ~HASH64withTransform() {}
|
||||
virtual ByteOrder getByteOrder() const = 0;
|
||||
virtual word32 getPadSize() const = 0;
|
||||
|
||||
virtual void Update(const byte*, word32);
|
||||
virtual void Final(byte*);
|
||||
|
||||
word32 GetBitCountLo() const { return loLen_ << 3; }
|
||||
word32 GetBitCountHi() const { return (loLen_ >> (8*sizeof(loLen_) - 3)) +
|
||||
(hiLen_ << 3); }
|
||||
enum { MaxDigestSz = 8, MaxBufferSz = 128 };
|
||||
protected:
|
||||
typedef word32 HashLengthType;
|
||||
word32 buffLen_; // in bytes
|
||||
HashLengthType loLen_; // length in bytes
|
||||
HashLengthType hiLen_; // length in bytes
|
||||
word64 digest_[MaxDigestSz];
|
||||
word64 buffer_[MaxBufferSz / sizeof(word64)];
|
||||
|
||||
virtual void Transform() = 0;
|
||||
|
||||
void AddLength(word32);
|
||||
};
|
||||
|
||||
#endif // WORD64_AVAILABLE
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_HASH_HPP
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* hamc.hpp implements HMAC, see RFC 2104
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_HMAC_HPP
|
||||
#define TAO_CRYPT_HMAC_HPP
|
||||
|
||||
#include "hash.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// HMAC class template
|
||||
template <class T>
|
||||
class HMAC {
|
||||
public:
|
||||
enum { IPAD = 0x36, OPAD = 0x5C };
|
||||
|
||||
HMAC() : ipad_(reinterpret_cast<byte*>(&ip_)),
|
||||
opad_(reinterpret_cast<byte*>(&op_)),
|
||||
innerHash_(reinterpret_cast<byte*>(&innerH_))
|
||||
{
|
||||
Init();
|
||||
}
|
||||
void Update(const byte*, word32);
|
||||
void Final(byte*);
|
||||
void Init();
|
||||
|
||||
void SetKey(const byte*, word32);
|
||||
private:
|
||||
byte* ipad_;
|
||||
byte* opad_;
|
||||
byte* innerHash_;
|
||||
bool innerHashKeyed_;
|
||||
T mac_;
|
||||
|
||||
// MSVC 6 HACK, gives compiler error if calculated in array
|
||||
enum { HMAC_BSIZE = T::BLOCK_SIZE / sizeof(word32),
|
||||
HMAC_DSIZE = T::DIGEST_SIZE / sizeof(word32) };
|
||||
|
||||
word32 ip_[HMAC_BSIZE]; // align ipad_ on word32
|
||||
word32 op_[HMAC_BSIZE]; // align opad_ on word32
|
||||
word32 innerH_[HMAC_DSIZE]; // align innerHash_ on word32
|
||||
|
||||
void KeyInnerHash();
|
||||
|
||||
HMAC(const HMAC&);
|
||||
HMAC& operator= (const HMAC&);
|
||||
};
|
||||
|
||||
|
||||
// Setup
|
||||
template <class T>
|
||||
void HMAC<T>::Init()
|
||||
{
|
||||
mac_.Init();
|
||||
innerHashKeyed_ = false;
|
||||
}
|
||||
|
||||
|
||||
// Key generation
|
||||
template <class T>
|
||||
void HMAC<T>::SetKey(const byte* key, word32 length)
|
||||
{
|
||||
Init();
|
||||
|
||||
if (length <= T::BLOCK_SIZE)
|
||||
memcpy(ipad_, key, length);
|
||||
else {
|
||||
mac_.Update(key, length);
|
||||
mac_.Final(ipad_);
|
||||
length = T::DIGEST_SIZE;
|
||||
}
|
||||
memset(ipad_ + length, 0, T::BLOCK_SIZE - length);
|
||||
|
||||
for (word32 i = 0; i < T::BLOCK_SIZE; i++) {
|
||||
opad_[i] = ipad_[i] ^ OPAD;
|
||||
ipad_[i] ^= IPAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Inner Key Hash
|
||||
template <class T>
|
||||
void HMAC<T>::KeyInnerHash()
|
||||
{
|
||||
mac_.Update(ipad_, T::BLOCK_SIZE);
|
||||
innerHashKeyed_ = true;
|
||||
}
|
||||
|
||||
|
||||
// Update
|
||||
template <class T>
|
||||
void HMAC<T>::Update(const byte* msg, word32 length)
|
||||
{
|
||||
if (!innerHashKeyed_)
|
||||
KeyInnerHash();
|
||||
mac_.Update(msg, length);
|
||||
}
|
||||
|
||||
|
||||
// Final
|
||||
template <class T>
|
||||
void HMAC<T>::Final(byte* hash)
|
||||
{
|
||||
if (!innerHashKeyed_)
|
||||
KeyInnerHash();
|
||||
mac_.Final(innerHash_);
|
||||
|
||||
mac_.Update(opad_, T::BLOCK_SIZE);
|
||||
mac_.Update(innerHash_, T::DIGEST_SIZE);
|
||||
mac_.Final(hash);
|
||||
|
||||
innerHashKeyed_ = false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_HMAC_HPP
|
||||
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* based on Wei Dai's integer.h from CryptoPP */
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_INTEGER_HPP
|
||||
#define TAO_CRYPT_INTEGER_HPP
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// 4250: dominance
|
||||
// 4660: explicitly instantiating a class already implicitly instantiated
|
||||
// 4661: no suitable definition provided for explicit template request
|
||||
// 4786: identifer was truncated in debug information
|
||||
// 4355: 'this' : used in base member initializer list
|
||||
# pragma warning(disable: 4250 4660 4661 4786 4355)
|
||||
#endif
|
||||
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "block.hpp"
|
||||
#include "random.hpp"
|
||||
#include "file.hpp"
|
||||
#include <string.h>
|
||||
#ifdef USE_SYS_STL
|
||||
#include <algorithm>
|
||||
#else
|
||||
#include "algorithm.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TAOCRYPT_X86ASM_AVAILABLE
|
||||
|
||||
#ifdef _M_IX86
|
||||
#if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || \
|
||||
(defined(__ICL) && (__ICL >= 500))
|
||||
#define SSE2_INTRINSICS_AVAILABLE
|
||||
#define TAOCRYPT_MM_MALLOC_AVAILABLE
|
||||
#elif defined(_MSC_VER)
|
||||
// _mm_free seems to be the only way to tell if the Processor Pack is
|
||||
//installed or not
|
||||
#include <malloc.h>
|
||||
#if defined(_mm_free)
|
||||
#define SSE2_INTRINSICS_AVAILABLE
|
||||
#define TAOCRYPT_MM_MALLOC_AVAILABLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// SSE2 intrinsics work in GCC 3.3 or later
|
||||
#if defined(__SSE2__) && (__GNUC__ == 4 || __GNUC_MAJOR__ > 3 || \
|
||||
__GNUC_MINOR__ > 2)
|
||||
#define SSE2_INTRINSICS_AVAILABLE
|
||||
#endif
|
||||
|
||||
#endif // X86ASM
|
||||
|
||||
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
#if defined(SSE2_INTRINSICS_AVAILABLE)
|
||||
|
||||
// Allocator handling proper alignment
|
||||
template <class T>
|
||||
class AlignedAllocator : public AllocatorBase<T>
|
||||
{
|
||||
public:
|
||||
typedef typename AllocatorBase<T>::pointer pointer;
|
||||
typedef typename AllocatorBase<T>::size_type size_type;
|
||||
|
||||
pointer allocate(size_type n, const void* = 0);
|
||||
void deallocate(void* p, size_type n);
|
||||
pointer reallocate(T* p, size_type oldSize, size_type newSize,
|
||||
bool preserve)
|
||||
{
|
||||
return StdReallocate(*this, p, oldSize, newSize, preserve);
|
||||
}
|
||||
|
||||
#if !(defined(TAOCRYPT_MALLOC_ALIGNMENT_IS_16) || \
|
||||
defined(TAOCRYPT_MEMALIGN_AVAILABLE) || \
|
||||
defined(TAOCRYPT_MM_MALLOC_AVAILABLE))
|
||||
#define TAOCRYPT_NO_ALIGNED_ALLOC
|
||||
AlignedAllocator() : m_pBlock(0) {}
|
||||
protected:
|
||||
void *m_pBlock;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef Block<word, AlignedAllocator<word> > AlignedWordBlock;
|
||||
#else
|
||||
typedef WordBlock AlignedWordBlock;
|
||||
#endif
|
||||
|
||||
|
||||
// general MIN
|
||||
template<typename T> inline
|
||||
const T& min(const T& a, const T& b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
|
||||
// general MAX
|
||||
template<typename T> inline
|
||||
const T& max(const T& a, const T& b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
|
||||
// Large Integer class
|
||||
class Integer {
|
||||
public:
|
||||
enum Sign {POSITIVE = 0, NEGATIVE = 1 };
|
||||
enum Signedness { UNSIGNED, SIGNED };
|
||||
enum RandomNumberType { ANY, PRIME };
|
||||
|
||||
class DivideByZero {};
|
||||
|
||||
Integer();
|
||||
Integer(const Integer& t);
|
||||
Integer(signed long value);
|
||||
Integer(Sign s, word highWord, word lowWord);
|
||||
|
||||
// BER Decode Source
|
||||
explicit Integer(Source&);
|
||||
|
||||
Integer(const byte* encodedInteger, unsigned int byteCount,
|
||||
Signedness s = UNSIGNED);
|
||||
|
||||
~Integer() {}
|
||||
|
||||
static const Integer& Zero();
|
||||
static const Integer& One();
|
||||
|
||||
Integer& Ref() { return *this; }
|
||||
|
||||
Integer(RandomNumberGenerator& rng, const Integer& min,
|
||||
const Integer& max);
|
||||
|
||||
static Integer Power2(unsigned int e);
|
||||
|
||||
unsigned int MinEncodedSize(Signedness = UNSIGNED) const;
|
||||
unsigned int Encode(byte* output, unsigned int outputLen,
|
||||
Signedness = UNSIGNED) const;
|
||||
|
||||
void Decode(const byte* input, unsigned int inputLen,
|
||||
Signedness = UNSIGNED);
|
||||
void Decode(Source&);
|
||||
|
||||
bool IsConvertableToLong() const;
|
||||
signed long ConvertToLong() const;
|
||||
|
||||
unsigned int BitCount() const;
|
||||
unsigned int ByteCount() const;
|
||||
unsigned int WordCount() const;
|
||||
|
||||
bool GetBit(unsigned int i) const;
|
||||
byte GetByte(unsigned int i) const;
|
||||
unsigned long GetBits(unsigned int i, unsigned int n) const;
|
||||
|
||||
bool IsZero() const { return !*this; }
|
||||
bool NotZero() const { return !IsZero(); }
|
||||
bool IsNegative() const { return sign_ == NEGATIVE; }
|
||||
bool NotNegative() const { return !IsNegative(); }
|
||||
bool IsPositive() const { return NotNegative() && NotZero(); }
|
||||
bool NotPositive() const { return !IsPositive(); }
|
||||
bool IsEven() const { return GetBit(0) == 0; }
|
||||
bool IsOdd() const { return GetBit(0) == 1; }
|
||||
|
||||
Integer& operator=(const Integer& t);
|
||||
Integer& operator+=(const Integer& t);
|
||||
Integer& operator-=(const Integer& t);
|
||||
Integer& operator*=(const Integer& t) { return *this = Times(t); }
|
||||
Integer& operator/=(const Integer& t)
|
||||
{ return *this = DividedBy(t);}
|
||||
Integer& operator%=(const Integer& t) { return *this = Modulo(t); }
|
||||
Integer& operator/=(word t) { return *this = DividedBy(t); }
|
||||
Integer& operator%=(word t) { return *this = Modulo(t); }
|
||||
Integer& operator<<=(unsigned int);
|
||||
Integer& operator>>=(unsigned int);
|
||||
|
||||
|
||||
void Randomize(RandomNumberGenerator &rng, unsigned int bitcount);
|
||||
void Randomize(RandomNumberGenerator &rng, const Integer &min,
|
||||
const Integer &max);
|
||||
|
||||
void SetBit(unsigned int n, bool value = 1);
|
||||
void SetByte(unsigned int n, byte value);
|
||||
|
||||
void Negate();
|
||||
void SetPositive() { sign_ = POSITIVE; }
|
||||
void SetNegative() { if (!!(*this)) sign_ = NEGATIVE; }
|
||||
void Swap(Integer& a);
|
||||
|
||||
bool operator!() const;
|
||||
Integer operator+() const {return *this;}
|
||||
Integer operator-() const;
|
||||
Integer& operator++();
|
||||
Integer& operator--();
|
||||
Integer operator++(int)
|
||||
{ Integer temp = *this; ++*this; return temp; }
|
||||
Integer operator--(int)
|
||||
{ Integer temp = *this; --*this; return temp; }
|
||||
|
||||
int Compare(const Integer& a) const;
|
||||
|
||||
Integer Plus(const Integer &b) const;
|
||||
Integer Minus(const Integer &b) const;
|
||||
Integer Times(const Integer &b) const;
|
||||
Integer DividedBy(const Integer &b) const;
|
||||
Integer Modulo(const Integer &b) const;
|
||||
Integer DividedBy(word b) const;
|
||||
word Modulo(word b) const;
|
||||
|
||||
Integer operator>>(unsigned int n) const { return Integer(*this)>>=n; }
|
||||
Integer operator<<(unsigned int n) const { return Integer(*this)<<=n; }
|
||||
|
||||
Integer AbsoluteValue() const;
|
||||
Integer Doubled() const { return Plus(*this); }
|
||||
Integer Squared() const { return Times(*this); }
|
||||
Integer SquareRoot() const;
|
||||
|
||||
bool IsSquare() const;
|
||||
bool IsUnit() const;
|
||||
|
||||
Integer MultiplicativeInverse() const;
|
||||
|
||||
friend Integer a_times_b_mod_c(const Integer& x, const Integer& y,
|
||||
const Integer& m);
|
||||
friend Integer a_exp_b_mod_c(const Integer& x, const Integer& e,
|
||||
const Integer& m);
|
||||
|
||||
static void Divide(Integer& r, Integer& q, const Integer& a,
|
||||
const Integer& d);
|
||||
static void Divide(word& r, Integer& q, const Integer& a, word d);
|
||||
static void DivideByPowerOf2(Integer& r, Integer& q, const Integer& a,
|
||||
unsigned int n);
|
||||
static Integer Gcd(const Integer& a, const Integer& n);
|
||||
|
||||
Integer InverseMod(const Integer& n) const;
|
||||
word InverseMod(word n) const;
|
||||
|
||||
private:
|
||||
friend class ModularArithmetic;
|
||||
friend class MontgomeryRepresentation;
|
||||
|
||||
Integer(word value, unsigned int length);
|
||||
int PositiveCompare(const Integer& t) const;
|
||||
|
||||
friend void PositiveAdd(Integer& sum, const Integer& a, const Integer& b);
|
||||
friend void PositiveSubtract(Integer& diff, const Integer& a,
|
||||
const Integer& b);
|
||||
friend void PositiveMultiply(Integer& product, const Integer& a,
|
||||
const Integer& b);
|
||||
friend void PositiveDivide(Integer& remainder, Integer& quotient, const
|
||||
Integer& dividend, const Integer& divisor);
|
||||
AlignedWordBlock reg_;
|
||||
Sign sign_;
|
||||
};
|
||||
|
||||
inline bool operator==(const Integer& a, const Integer& b)
|
||||
{return a.Compare(b)==0;}
|
||||
inline bool operator!=(const Integer& a, const Integer& b)
|
||||
{return a.Compare(b)!=0;}
|
||||
inline bool operator> (const Integer& a, const Integer& b)
|
||||
{return a.Compare(b)> 0;}
|
||||
inline bool operator>=(const Integer& a, const Integer& b)
|
||||
{return a.Compare(b)>=0;}
|
||||
inline bool operator< (const Integer& a, const Integer& b)
|
||||
{return a.Compare(b)< 0;}
|
||||
inline bool operator<=(const Integer& a, const Integer& b)
|
||||
{return a.Compare(b)<=0;}
|
||||
|
||||
inline Integer operator+(const Integer &a, const Integer &b)
|
||||
{return a.Plus(b);}
|
||||
inline Integer operator-(const Integer &a, const Integer &b)
|
||||
{return a.Minus(b);}
|
||||
inline Integer operator*(const Integer &a, const Integer &b)
|
||||
{return a.Times(b);}
|
||||
inline Integer operator/(const Integer &a, const Integer &b)
|
||||
{return a.DividedBy(b);}
|
||||
inline Integer operator%(const Integer &a, const Integer &b)
|
||||
{return a.Modulo(b);}
|
||||
inline Integer operator/(const Integer &a, word b) {return a.DividedBy(b);}
|
||||
inline word operator%(const Integer &a, word b) {return a.Modulo(b);}
|
||||
|
||||
inline void swap(Integer &a, Integer &b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
|
||||
Integer CRT(const Integer& xp, const Integer& p, const Integer& xq,
|
||||
const Integer& q, const Integer& u);
|
||||
|
||||
inline Integer ModularExponentiation(const Integer& a, const Integer& e,
|
||||
const Integer& m)
|
||||
{
|
||||
return a_exp_b_mod_c(a, e, m);
|
||||
}
|
||||
|
||||
Integer ModularRoot(const Integer& a, const Integer& dp, const Integer& dq,
|
||||
const Integer& p, const Integer& q, const Integer& u);
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_INTEGER_HPP
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* kernelc.hpp provides support for C std lib when compiled in kernel mode
|
||||
*/
|
||||
|
||||
#ifndef TAOCRYPT_KERNELC_HPP
|
||||
#define TAOCRYPT_KERNELC_HPP
|
||||
|
||||
#include <linux/types.h> // get right size_t
|
||||
|
||||
// system functions that c++ doesn't like headers for
|
||||
|
||||
extern "C" void* memcpy(void*, const void*, size_t);
|
||||
extern "C" void* memset(void*, int, size_t);
|
||||
extern "C" void printk(char *fmt, ...);
|
||||
|
||||
#define KERN_ERR "<3>" /* error conditions */
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#define assert(p) ((void)0)
|
||||
#else
|
||||
#define assert(expr) \
|
||||
if (!(expr)) { \
|
||||
printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
|
||||
#expr,__FILE__,__FUNCTION__,__LINE__); }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // TAOCRYPT_KERNELC_HPP
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* md2.hpp provides MD2 digest support, see RFC 1319
|
||||
*/
|
||||
|
||||
#ifndef TAO_CRYPT_MD2_HPP
|
||||
#define TAO_CRYPT_MD2_HPP
|
||||
|
||||
|
||||
#include "hash.hpp"
|
||||
#include "block.hpp"
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// MD2 digest
|
||||
class MD2 : public HASH {
|
||||
public:
|
||||
enum { BLOCK_SIZE = 16, DIGEST_SIZE = 16, PAD_SIZE = 16, X_SIZE = 48 };
|
||||
MD2();
|
||||
|
||||
word32 getBlockSize() const { return BLOCK_SIZE; }
|
||||
word32 getDigestSize() const { return DIGEST_SIZE; }
|
||||
|
||||
void Update(const byte*, word32);
|
||||
void Final(byte*);
|
||||
|
||||
void Init();
|
||||
void Swap(MD2&);
|
||||
private:
|
||||
ByteBlock X_, C_, buffer_;
|
||||
word32 count_; // bytes % PAD_SIZE
|
||||
|
||||
MD2(const MD2&);
|
||||
MD2& operator=(const MD2&);
|
||||
};
|
||||
|
||||
inline void swap(MD2& a, MD2& b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_MD2_HPP
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* md4.hpp provides MD4 digest support
|
||||
* WANRING: MD4 is considered insecure, only use if you have to, e.g., yaSSL
|
||||
* libcurl supports needs this for NTLM authentication
|
||||
*/
|
||||
|
||||
#ifndef TAO_CRYPT_MD4_HPP
|
||||
#define TAO_CRYPT_MD4_HPP
|
||||
|
||||
#include "hash.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// MD4 digest
|
||||
class MD4 : public HASHwithTransform {
|
||||
public:
|
||||
enum { BLOCK_SIZE = 64, DIGEST_SIZE = 16, PAD_SIZE = 56,
|
||||
TAO_BYTE_ORDER = LittleEndianOrder }; // in Bytes
|
||||
MD4() : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE)
|
||||
{ Init(); }
|
||||
ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); }
|
||||
word32 getBlockSize() const { return BLOCK_SIZE; }
|
||||
word32 getDigestSize() const { return DIGEST_SIZE; }
|
||||
word32 getPadSize() const { return PAD_SIZE; }
|
||||
|
||||
MD4(const MD4&);
|
||||
MD4& operator= (const MD4&);
|
||||
|
||||
void Init();
|
||||
void Swap(MD4&);
|
||||
private:
|
||||
void Transform();
|
||||
};
|
||||
|
||||
inline void swap(MD4& a, MD4& b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_MD4_HPP
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* md5.hpp provides MD5 digest support, see RFC 1321
|
||||
*/
|
||||
|
||||
#ifndef TAO_CRYPT_MD5_HPP
|
||||
#define TAO_CRYPT_MD5_HPP
|
||||
|
||||
#include "hash.hpp"
|
||||
|
||||
|
||||
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
|
||||
#define DO_MD5_ASM
|
||||
#endif
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// MD5 digest
|
||||
class MD5 : public HASHwithTransform {
|
||||
public:
|
||||
enum { BLOCK_SIZE = 64, DIGEST_SIZE = 16, PAD_SIZE = 56,
|
||||
TAO_BYTE_ORDER = LittleEndianOrder }; // in Bytes
|
||||
MD5() : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE)
|
||||
{ Init(); }
|
||||
ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); }
|
||||
word32 getBlockSize() const { return BLOCK_SIZE; }
|
||||
word32 getDigestSize() const { return DIGEST_SIZE; }
|
||||
word32 getPadSize() const { return PAD_SIZE; }
|
||||
|
||||
MD5(const MD5&);
|
||||
MD5& operator= (const MD5&);
|
||||
|
||||
#ifdef DO_MD5_ASM
|
||||
void Update(const byte*, word32);
|
||||
#endif
|
||||
|
||||
void Init();
|
||||
void Swap(MD5&);
|
||||
private:
|
||||
void Transform();
|
||||
void AsmTransform(const byte* data, word32 times);
|
||||
};
|
||||
|
||||
inline void swap(MD5& a, MD5& b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_MD5_HPP
|
||||
|
||||
@@ -0,0 +1,886 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* based on Wei Dai's misc.h from CryptoPP */
|
||||
|
||||
#ifndef TAO_CRYPT_MISC_HPP
|
||||
#define TAO_CRYPT_MISC_HPP
|
||||
|
||||
|
||||
#if !defined(DO_TAOCRYPT_KERNEL_MODE)
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
#include "kernelc.hpp"
|
||||
#endif
|
||||
|
||||
#include "types.hpp"
|
||||
#include "type_traits.hpp"
|
||||
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// Delete static singleton holders
|
||||
void CleanUp();
|
||||
|
||||
|
||||
#ifdef YASSL_PURE_C
|
||||
|
||||
// library allocation
|
||||
struct new_t {}; // TaoCrypt New type
|
||||
extern new_t tc; // pass in parameter
|
||||
|
||||
} // namespace TaoCrypt
|
||||
|
||||
void* operator new (size_t, TaoCrypt::new_t);
|
||||
void* operator new[](size_t, TaoCrypt::new_t);
|
||||
|
||||
void operator delete (void*, TaoCrypt::new_t);
|
||||
void operator delete[](void*, TaoCrypt::new_t);
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
template<typename T>
|
||||
void tcDelete(T* ptr)
|
||||
{
|
||||
if (ptr) ptr->~T();
|
||||
::operator delete(ptr, TaoCrypt::tc);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void tcArrayDelete(T* ptr)
|
||||
{
|
||||
// can't do array placement destruction since not tracking size in
|
||||
// allocation, only allow builtins to use array placement since they
|
||||
// don't need destructors called
|
||||
typedef char builtin[IsFundamentalType<T>::Yes ? 1 : -1];
|
||||
(void)sizeof(builtin);
|
||||
|
||||
::operator delete[](ptr, TaoCrypt::tc);
|
||||
}
|
||||
|
||||
#define NEW_TC new (TaoCrypt::tc)
|
||||
|
||||
|
||||
// to resolve compiler generated operator delete on base classes with
|
||||
// virtual destructors (when on stack), make sure doesn't get called
|
||||
class virtual_base {
|
||||
public:
|
||||
static void operator delete(void*) { assert(0); }
|
||||
};
|
||||
|
||||
#else // YASSL_PURE_C
|
||||
|
||||
|
||||
template<typename T>
|
||||
void tcDelete(T* ptr)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void tcArrayDelete(T* ptr)
|
||||
{
|
||||
delete[] ptr;
|
||||
}
|
||||
|
||||
#define NEW_TC new
|
||||
|
||||
class virtual_base {};
|
||||
|
||||
|
||||
#endif // YASSL_PURE_C
|
||||
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
|
||||
#define INTEL_INTRINSICS
|
||||
#define FAST_ROTATE
|
||||
#elif defined(__MWERKS__) && TARGET_CPU_PPC
|
||||
#define PPC_INTRINSICS
|
||||
#define FAST_ROTATE
|
||||
#elif defined(__GNUC__) && defined(__i386__)
|
||||
// GCC does peephole optimizations which should result in using rotate
|
||||
// instructions
|
||||
#define FAST_ROTATE
|
||||
#endif
|
||||
|
||||
|
||||
// no gas on these systems ?, disable for now
|
||||
#if defined(__sun__) || defined (__QNX__) || defined (__APPLE__)
|
||||
#define TAOCRYPT_DISABLE_X86ASM
|
||||
#endif
|
||||
|
||||
// icc problem with -03 and integer, disable for now
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#define TAOCRYPT_DISABLE_X86ASM
|
||||
#endif
|
||||
|
||||
|
||||
// Turn on ia32 ASM for Big Integer
|
||||
// CodeWarrior defines _MSC_VER
|
||||
#if !defined(TAOCRYPT_DISABLE_X86ASM) && ((defined(_MSC_VER) && \
|
||||
!defined(__MWERKS__) && defined(_M_IX86)) || \
|
||||
(defined(__GNUC__) && defined(__i386__)))
|
||||
#define TAOCRYPT_X86ASM_AVAILABLE
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TAOCRYPT_X86ASM_AVAILABLE
|
||||
bool HaveCpuId();
|
||||
bool IsPentium();
|
||||
void CpuId(word32 input, word32 *output);
|
||||
|
||||
extern bool isMMX;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// Turn on ia32 ASM for Ciphers and Message Digests
|
||||
// Seperate define since these are more complex, use member offsets
|
||||
// and user may want to turn off while leaving Big Integer optos on
|
||||
#if defined(TAOCRYPT_X86ASM_AVAILABLE) && !defined(DISABLE_TAO_ASM)
|
||||
#define TAO_ASM
|
||||
#endif
|
||||
|
||||
|
||||
// Extra word in older vtable implementations, for ASM member offset
|
||||
#if defined(__GNUC__) && __GNUC__ < 3
|
||||
#define OLD_GCC_OFFSET
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# define TAOCRYPT_MALLOC_ALIGNMENT_IS_16
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
|
||||
# define TAOCRYPT_MEMALIGN_AVAILABLE
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define TAOCRYPT_WIN32_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) || defined(__MACH__)
|
||||
#define TAOCRYPT_UNIX_AVAILABLE
|
||||
#endif
|
||||
|
||||
|
||||
// VC60 workaround: it doesn't allow typename in some places
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
#define CPP_TYPENAME
|
||||
#else
|
||||
#define CPP_TYPENAME typename
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define TAOCRYPT_NO_VTABLE __declspec(novtable)
|
||||
#else
|
||||
#define TAOCRYPT_NO_VTABLE
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_SYS_STL
|
||||
// use system STL
|
||||
#define STL_NAMESPACE std
|
||||
#else
|
||||
// use mySTL
|
||||
#define STL_NAMESPACE mySTL
|
||||
#endif
|
||||
|
||||
|
||||
// ***************** DLL related ********************
|
||||
|
||||
#ifdef TAOCRYPT_WIN32_AVAILABLE
|
||||
|
||||
#ifdef TAOCRYPT_EXPORTS
|
||||
#define TAOCRYPT_IS_DLL
|
||||
#define TAOCRYPT_DLL __declspec(dllexport)
|
||||
#elif defined(TAOCRYPT_IMPORTS)
|
||||
#define TAOCRYPT_IS_DLL
|
||||
#define TAOCRYPT_DLL __declspec(dllimport)
|
||||
#else
|
||||
#define TAOCRYPT_DLL
|
||||
#endif // EXPORTS
|
||||
|
||||
#define TAOCRYPT_API __stdcall
|
||||
#define TAOCRYPT_CDECL __cdecl
|
||||
|
||||
#else // TAOCRYPT_WIN32_AVAILABLE
|
||||
|
||||
#define TAOCRYPT_DLL
|
||||
#define TAOCRYPT_API
|
||||
#define TAOCRYPT_CDECL
|
||||
|
||||
#endif // TAOCRYPT_WIN32_AVAILABLE
|
||||
|
||||
|
||||
// ****************** tempalte stuff *******************
|
||||
|
||||
|
||||
#if defined(TAOCRYPT_MANUALLY_INSTANTIATE_TEMPLATES) && \
|
||||
!defined(TAOCRYPT_IMPORTS)
|
||||
#define TAOCRYPT_DLL_TEMPLATE_CLASS template class TAOCRYPT_DLL
|
||||
#elif defined(__MWERKS__)
|
||||
#define TAOCRYPT_DLL_TEMPLATE_CLASS extern class TAOCRYPT_DLL
|
||||
#else
|
||||
#define TAOCRYPT_DLL_TEMPLATE_CLASS extern template class TAOCRYPT_DLL
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TAOCRYPT_MANUALLY_INSTANTIATE_TEMPLATES) && \
|
||||
!defined(TAOCRYPT_EXPORTS)
|
||||
#define TAOCRYPT_STATIC_TEMPLATE_CLASS template class
|
||||
#elif defined(__MWERKS__)
|
||||
#define TAOCRYPT_STATIC_TEMPLATE_CLASS extern class
|
||||
#else
|
||||
#define TAOCRYPT_STATIC_TEMPLATE_CLASS extern template class
|
||||
#endif
|
||||
|
||||
|
||||
// ************** compile-time assertion ***************
|
||||
|
||||
template <bool b>
|
||||
struct CompileAssert
|
||||
{
|
||||
static char dummy[2*b-1];
|
||||
};
|
||||
|
||||
#define TAOCRYPT_COMPILE_ASSERT(assertion) \
|
||||
TAOCRYPT_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
|
||||
|
||||
#if defined(TAOCRYPT_EXPORTS) || defined(TAOCRYPT_IMPORTS)
|
||||
#define TAOCRYPT_COMPILE_ASSERT_INSTANCE(assertion, instance)
|
||||
#else
|
||||
#define TAOCRYPT_COMPILE_ASSERT_INSTANCE(assertion, instance) \
|
||||
(void)sizeof(CompileAssert<(assertion)>)
|
||||
#endif
|
||||
|
||||
#define TAOCRYPT_ASSERT_JOIN(X, Y) TAOCRYPT_DO_ASSERT_JOIN(X, Y)
|
||||
|
||||
#define TAOCRYPT_DO_ASSERT_JOIN(X, Y) X##Y
|
||||
|
||||
|
||||
/*************** helpers *****************************/
|
||||
|
||||
inline unsigned int BitsToBytes(unsigned int bitCount)
|
||||
{
|
||||
return ((bitCount+7)/(8));
|
||||
}
|
||||
|
||||
inline unsigned int BytesToWords(unsigned int byteCount)
|
||||
{
|
||||
return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
|
||||
}
|
||||
|
||||
inline unsigned int BitsToWords(unsigned int bitCount)
|
||||
{
|
||||
return ((bitCount+WORD_BITS-1)/(WORD_BITS));
|
||||
}
|
||||
|
||||
inline void CopyWords(word* r, const word* a, word32 n)
|
||||
{
|
||||
for (word32 i = 0; i < n; i++)
|
||||
r[i] = a[i];
|
||||
}
|
||||
|
||||
inline unsigned int CountWords(const word* X, unsigned int N)
|
||||
{
|
||||
while (N && X[N-1]==0)
|
||||
N--;
|
||||
return N;
|
||||
}
|
||||
|
||||
inline void SetWords(word* r, word a, unsigned int n)
|
||||
{
|
||||
for (unsigned int i=0; i<n; i++)
|
||||
r[i] = a;
|
||||
}
|
||||
|
||||
enum ByteOrder { LittleEndianOrder = 0, BigEndianOrder = 1 };
|
||||
enum CipherDir {ENCRYPTION, DECRYPTION};
|
||||
|
||||
inline CipherDir ReverseDir(CipherDir dir)
|
||||
{
|
||||
return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
|
||||
}
|
||||
|
||||
template <typename ENUM_TYPE, int VALUE>
|
||||
struct EnumToType
|
||||
{
|
||||
static ENUM_TYPE ToEnum() { return (ENUM_TYPE)VALUE; }
|
||||
};
|
||||
|
||||
typedef EnumToType<ByteOrder, LittleEndianOrder> LittleEndian;
|
||||
typedef EnumToType<ByteOrder, BigEndianOrder> BigEndian;
|
||||
|
||||
|
||||
#ifndef BIG_ENDIAN_ORDER
|
||||
typedef LittleEndian HostByteOrder;
|
||||
#else
|
||||
typedef BigEndian HostByteOrder;
|
||||
#endif
|
||||
|
||||
inline ByteOrder GetHostByteOrder()
|
||||
{
|
||||
return HostByteOrder::ToEnum();
|
||||
}
|
||||
|
||||
inline bool HostByteOrderIs(ByteOrder order)
|
||||
{
|
||||
return order == GetHostByteOrder();
|
||||
}
|
||||
|
||||
|
||||
void xorbuf(byte*, const byte*, unsigned int);
|
||||
|
||||
|
||||
template <class T>
|
||||
inline bool IsPowerOf2(T n)
|
||||
{
|
||||
return n > 0 && (n & (n-1)) == 0;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
inline T2 ModPowerOf2(T1 a, T2 b)
|
||||
{
|
||||
assert(IsPowerOf2(b));
|
||||
return T2(a) & (b-1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T RoundDownToMultipleOf(T n, T m)
|
||||
{
|
||||
return n - (IsPowerOf2(m) ? ModPowerOf2(n, m) : (n%m));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T RoundUpToMultipleOf(T n, T m)
|
||||
{
|
||||
return RoundDownToMultipleOf(n+m-1, m);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline unsigned int GetAlignment(T* dummy = 0) // VC60 workaround
|
||||
{
|
||||
#if (_MSC_VER >= 1300)
|
||||
return __alignof(T);
|
||||
#elif defined(__GNUC__)
|
||||
return __alignof__(T);
|
||||
#else
|
||||
return sizeof(T);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool IsAlignedOn(const void* p, unsigned int alignment)
|
||||
{
|
||||
return IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0
|
||||
: (size_t)p % alignment == 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool IsAligned(const void* p, T* dummy = 0) // VC60 workaround
|
||||
{
|
||||
return IsAlignedOn(p, GetAlignment<T>());
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline T rotlFixed(T x, unsigned int y)
|
||||
{
|
||||
assert(y < sizeof(T)*8);
|
||||
return (x<<y) | (x>>(sizeof(T)*8-y));
|
||||
}
|
||||
|
||||
template <class T> inline T rotrFixed(T x, unsigned int y)
|
||||
{
|
||||
assert(y < sizeof(T)*8);
|
||||
return (x>>y) | (x<<(sizeof(T)*8-y));
|
||||
}
|
||||
|
||||
#ifdef INTEL_INTRINSICS
|
||||
|
||||
#pragma intrinsic(_lrotl, _lrotr)
|
||||
|
||||
template<> inline word32 rotlFixed(word32 x, word32 y)
|
||||
{
|
||||
assert(y < 32);
|
||||
return y ? _lrotl(x, y) : x;
|
||||
}
|
||||
|
||||
template<> inline word32 rotrFixed(word32 x, word32 y)
|
||||
{
|
||||
assert(y < 32);
|
||||
return y ? _lrotr(x, y) : x;
|
||||
}
|
||||
|
||||
#endif // INTEL_INTRINSICS
|
||||
|
||||
#ifndef min
|
||||
inline word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
inline word32 ByteReverse(word32 value)
|
||||
{
|
||||
#ifdef PPC_INTRINSICS
|
||||
// PPC: load reverse indexed instruction
|
||||
return (word32)__lwbrx(&value,0);
|
||||
#elif defined(FAST_ROTATE)
|
||||
// 5 instructions with rotate instruction, 9 without
|
||||
return (rotrFixed(value, 8U) & 0xff00ff00) |
|
||||
(rotlFixed(value, 8U) & 0x00ff00ff);
|
||||
#else
|
||||
// 6 instructions with rotate instruction, 8 without
|
||||
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
|
||||
return rotlFixed(value, 16U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef WORD64_AVAILABLE
|
||||
|
||||
inline word64 ByteReverse(word64 value)
|
||||
{
|
||||
#ifdef TAOCRYPT_SLOW_WORD64
|
||||
return (word64(ByteReverse(word32(value))) << 32) |
|
||||
ByteReverse(word32(value>>32));
|
||||
#else
|
||||
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
|
||||
((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
|
||||
value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
|
||||
((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
|
||||
return rotlFixed(value, 32U);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // WORD64_AVAILABLE
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline void ByteReverse(T* out, const T* in, word32 byteCount)
|
||||
{
|
||||
assert(byteCount % sizeof(T) == 0);
|
||||
word32 count = byteCount/sizeof(T);
|
||||
for (word32 i=0; i<count; i++)
|
||||
out[i] = ByteReverse(in[i]);
|
||||
}
|
||||
|
||||
inline void ByteReverse(byte* out, const byte* in, word32 byteCount)
|
||||
{
|
||||
word32* o = reinterpret_cast<word32*>(out);
|
||||
const word32* i = reinterpret_cast<const word32*>(in);
|
||||
ByteReverse(o, i, byteCount);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline T ByteReverseIf(T value, ByteOrder order)
|
||||
{
|
||||
return HostByteOrderIs(order) ? value : ByteReverse(value);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline void ByteReverseIf(T* out, const T* in, word32 bc, ByteOrder order)
|
||||
{
|
||||
if (!HostByteOrderIs(order))
|
||||
ByteReverse(out, in, bc);
|
||||
else if (out != in)
|
||||
memcpy(out, in, bc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// do Asm Reverse is host is Little and x86asm
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
#ifdef TAOCRYPT_X86ASM_AVAILABLE
|
||||
#define LittleReverse AsmReverse
|
||||
#else
|
||||
#define LittleReverse ByteReverse
|
||||
#endif
|
||||
#else
|
||||
#define LittleReverse
|
||||
#endif
|
||||
|
||||
|
||||
// do Asm Reverse is host is Big and x86asm
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
#ifdef TAOCRYPT_X86ASM_AVAILABLE
|
||||
#define BigReverse AsmReverse
|
||||
#else
|
||||
#define BigReverse ByteReverse
|
||||
#endif
|
||||
#else
|
||||
#define BigReverse
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TAOCRYPT_X86ASM_AVAILABLE
|
||||
|
||||
// faster than rotate, use bswap
|
||||
|
||||
inline word32 AsmReverse(word32 wd)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
__asm__
|
||||
(
|
||||
"bswap %1"
|
||||
: "=r"(wd)
|
||||
: "0"(wd)
|
||||
);
|
||||
#else
|
||||
__asm
|
||||
{
|
||||
mov eax, wd
|
||||
bswap eax
|
||||
mov wd, eax
|
||||
}
|
||||
#endif
|
||||
return wd;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
template <class T>
|
||||
inline void GetUserKey(ByteOrder order, T* out, word32 outlen, const byte* in,
|
||||
word32 inlen)
|
||||
{
|
||||
const unsigned int U = sizeof(T);
|
||||
assert(inlen <= outlen*U);
|
||||
memcpy(out, in, inlen);
|
||||
memset((byte *)out+inlen, 0, outlen*U-inlen);
|
||||
ByteReverseIf(out, out, RoundUpToMultipleOf(inlen, U), order);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// disable conversion warning
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
|
||||
inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block,
|
||||
byte*)
|
||||
{
|
||||
return block[0];
|
||||
}
|
||||
|
||||
inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte* block,
|
||||
word16*)
|
||||
{
|
||||
return (order == BigEndianOrder)
|
||||
? block[1] | (block[0] << 8)
|
||||
: block[0] | (block[1] << 8);
|
||||
}
|
||||
|
||||
inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte* block,
|
||||
word32*)
|
||||
{
|
||||
return (order == BigEndianOrder)
|
||||
? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16)
|
||||
| (word32(block[0]) << 24)
|
||||
: word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16)
|
||||
| (word32(block[3]) << 24);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T UnalignedGetWord(ByteOrder order, const byte *block, T* dummy = 0)
|
||||
{
|
||||
return UnalignedGetWordNonTemplate(order, block, dummy);
|
||||
}
|
||||
|
||||
inline void UnalignedPutWord(ByteOrder order, byte *block, byte value,
|
||||
const byte *xorBlock = 0)
|
||||
{
|
||||
block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
|
||||
}
|
||||
|
||||
#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
|
||||
|
||||
inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value,
|
||||
const byte *xorBlock = 0)
|
||||
{
|
||||
if (order == BigEndianOrder)
|
||||
{
|
||||
block[0] = GETBYTE(value, 1);
|
||||
block[1] = GETBYTE(value, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
block[0] = GETBYTE(value, 0);
|
||||
block[1] = GETBYTE(value, 1);
|
||||
}
|
||||
|
||||
if (xorBlock)
|
||||
{
|
||||
block[0] ^= xorBlock[0];
|
||||
block[1] ^= xorBlock[1];
|
||||
}
|
||||
}
|
||||
|
||||
inline void UnalignedPutWord(ByteOrder order, byte* block, word32 value,
|
||||
const byte* xorBlock = 0)
|
||||
{
|
||||
if (order == BigEndianOrder)
|
||||
{
|
||||
block[0] = GETBYTE(value, 3);
|
||||
block[1] = GETBYTE(value, 2);
|
||||
block[2] = GETBYTE(value, 1);
|
||||
block[3] = GETBYTE(value, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
block[0] = GETBYTE(value, 0);
|
||||
block[1] = GETBYTE(value, 1);
|
||||
block[2] = GETBYTE(value, 2);
|
||||
block[3] = GETBYTE(value, 3);
|
||||
}
|
||||
|
||||
if (xorBlock)
|
||||
{
|
||||
block[0] ^= xorBlock[0];
|
||||
block[1] ^= xorBlock[1];
|
||||
block[2] ^= xorBlock[2];
|
||||
block[3] ^= xorBlock[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
|
||||
{
|
||||
if (assumeAligned)
|
||||
{
|
||||
assert(IsAligned<T>(block));
|
||||
return ByteReverseIf(*reinterpret_cast<const T *>(block), order);
|
||||
}
|
||||
else
|
||||
return UnalignedGetWord<T>(order, block);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void GetWord(bool assumeAligned, ByteOrder order, T &result,
|
||||
const byte *block)
|
||||
{
|
||||
result = GetWord<T>(assumeAligned, order, block);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void PutWord(bool assumeAligned, ByteOrder order, byte* block, T value,
|
||||
const byte *xorBlock = 0)
|
||||
{
|
||||
if (assumeAligned)
|
||||
{
|
||||
assert(IsAligned<T>(block));
|
||||
if (xorBlock)
|
||||
*reinterpret_cast<T *>(block) = ByteReverseIf(value, order)
|
||||
^ *reinterpret_cast<const T *>(xorBlock);
|
||||
else
|
||||
*reinterpret_cast<T *>(block) = ByteReverseIf(value, order);
|
||||
}
|
||||
else
|
||||
UnalignedPutWord(order, block, value, xorBlock);
|
||||
}
|
||||
|
||||
template <class T, class B, bool A=true>
|
||||
class GetBlock
|
||||
{
|
||||
public:
|
||||
GetBlock(const void *block)
|
||||
: m_block((const byte *)block) {}
|
||||
|
||||
template <class U>
|
||||
inline GetBlock<T, B, A> & operator()(U &x)
|
||||
{
|
||||
TAOCRYPT_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
|
||||
x = GetWord<T>(A, B::ToEnum(), m_block);
|
||||
m_block += sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const byte *m_block;
|
||||
};
|
||||
|
||||
template <class T, class B, bool A = true>
|
||||
class PutBlock
|
||||
{
|
||||
public:
|
||||
PutBlock(const void *xorBlock, void *block)
|
||||
: m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
|
||||
|
||||
template <class U>
|
||||
inline PutBlock<T, B, A> & operator()(U x)
|
||||
{
|
||||
PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
|
||||
m_block += sizeof(T);
|
||||
if (m_xorBlock)
|
||||
m_xorBlock += sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const byte *m_xorBlock;
|
||||
byte *m_block;
|
||||
};
|
||||
|
||||
template <class T, class B, bool A=true>
|
||||
struct BlockGetAndPut
|
||||
{
|
||||
// function needed because of C++ grammatical ambiguity between
|
||||
// expression-statements and declarations
|
||||
static inline GetBlock<T, B, A> Get(const void *block)
|
||||
{return GetBlock<T, B, A>(block);}
|
||||
typedef PutBlock<T, B, A> Put;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <bool overflow> struct SafeShifter;
|
||||
|
||||
template<> struct SafeShifter<true>
|
||||
{
|
||||
template <class T>
|
||||
static inline T RightShift(T value, unsigned int bits)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline T LeftShift(T value, unsigned int bits)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct SafeShifter<false>
|
||||
{
|
||||
template <class T>
|
||||
static inline T RightShift(T value, unsigned int bits)
|
||||
{
|
||||
return value >> bits;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline T LeftShift(T value, unsigned int bits)
|
||||
{
|
||||
return value << bits;
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int bits, class T>
|
||||
inline T SafeRightShift(T value)
|
||||
{
|
||||
return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
|
||||
}
|
||||
|
||||
template <unsigned int bits, class T>
|
||||
inline T SafeLeftShift(T value)
|
||||
{
|
||||
return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
word ShiftWordsLeftByBits(word* r, unsigned int n, unsigned int shiftBits)
|
||||
{
|
||||
assert (shiftBits<WORD_BITS);
|
||||
word u, carry=0;
|
||||
if (shiftBits)
|
||||
for (unsigned int i=0; i<n; i++)
|
||||
{
|
||||
u = r[i];
|
||||
r[i] = (u << shiftBits) | carry;
|
||||
carry = u >> (WORD_BITS-shiftBits);
|
||||
}
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
word ShiftWordsRightByBits(word* r, unsigned int n, unsigned int shiftBits)
|
||||
{
|
||||
assert (shiftBits<WORD_BITS);
|
||||
word u, carry=0;
|
||||
if (shiftBits)
|
||||
for (int i=n-1; i>=0; i--)
|
||||
{
|
||||
u = r[i];
|
||||
r[i] = (u >> shiftBits) | carry;
|
||||
carry = u << (WORD_BITS-shiftBits);
|
||||
}
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void ShiftWordsLeftByWords(word* r, unsigned int n, unsigned int shiftWords)
|
||||
{
|
||||
shiftWords = min(shiftWords, n);
|
||||
if (shiftWords)
|
||||
{
|
||||
for (unsigned int i=n-1; i>=shiftWords; i--)
|
||||
r[i] = r[i-shiftWords];
|
||||
SetWords(r, 0, shiftWords);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void ShiftWordsRightByWords(word* r, unsigned int n, unsigned int shiftWords)
|
||||
{
|
||||
shiftWords = min(shiftWords, n);
|
||||
if (shiftWords)
|
||||
{
|
||||
for (unsigned int i=0; i+shiftWords<n; i++)
|
||||
r[i] = r[i+shiftWords];
|
||||
SetWords(r+n-shiftWords, 0, shiftWords);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T1, class T2>
|
||||
inline T1 SaturatingSubtract(T1 a, T2 b)
|
||||
{
|
||||
TAOCRYPT_COMPILE_ASSERT_INSTANCE(T1(-1)>0, 0); // T1 is unsigned type
|
||||
TAOCRYPT_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1); // T2 is unsigned type
|
||||
return T1((a > b) ? (a - b) : 0);
|
||||
}
|
||||
|
||||
|
||||
// declares
|
||||
unsigned int BytePrecision(word value);
|
||||
unsigned int BitPrecision(word);
|
||||
word Crop(word value, unsigned int size);
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_MISC_HPP
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
Copyright (C) 2000-2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
/* based on Wei Dai's modarith.h from CryptoPP */
|
||||
|
||||
|
||||
#ifndef TAO_CRYPT_MODARITH_HPP
|
||||
#define TAO_CRYPT_MODARITH_HPP
|
||||
|
||||
#include "misc.hpp"
|
||||
#include "algebra.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// ModularArithmetic
|
||||
class ModularArithmetic : public AbstractRing
|
||||
{
|
||||
public:
|
||||
|
||||
typedef int RandomizationParameter;
|
||||
typedef Integer Element;
|
||||
|
||||
ModularArithmetic(const Integer &modulus = Integer::One())
|
||||
: modulus(modulus), result((word)0, modulus.reg_.size()) {}
|
||||
|
||||
ModularArithmetic(const ModularArithmetic &ma)
|
||||
: AbstractRing(),
|
||||
modulus(ma.modulus), result((word)0, modulus.reg_.size()) {}
|
||||
|
||||
const Integer& GetModulus() const {return modulus;}
|
||||
void SetModulus(const Integer &newModulus)
|
||||
{
|
||||
modulus = newModulus;
|
||||
result.reg_.resize(modulus.reg_.size());
|
||||
}
|
||||
|
||||
virtual bool IsMontgomeryRepresentation() const {return false;}
|
||||
|
||||
virtual Integer ConvertIn(const Integer &a) const
|
||||
{return a%modulus;}
|
||||
|
||||
virtual Integer ConvertOut(const Integer &a) const
|
||||
{return a;}
|
||||
|
||||
const Integer& Half(const Integer &a) const;
|
||||
|
||||
bool Equal(const Integer &a, const Integer &b) const
|
||||
{return a==b;}
|
||||
|
||||
const Integer& Identity() const
|
||||
{return Integer::Zero();}
|
||||
|
||||
const Integer& Add(const Integer &a, const Integer &b) const;
|
||||
|
||||
Integer& Accumulate(Integer &a, const Integer &b) const;
|
||||
|
||||
const Integer& Inverse(const Integer &a) const;
|
||||
|
||||
const Integer& Subtract(const Integer &a, const Integer &b) const;
|
||||
|
||||
Integer& Reduce(Integer &a, const Integer &b) const;
|
||||
|
||||
const Integer& Double(const Integer &a) const
|
||||
{return Add(a, a);}
|
||||
|
||||
const Integer& MultiplicativeIdentity() const
|
||||
{return Integer::One();}
|
||||
|
||||
const Integer& Multiply(const Integer &a, const Integer &b) const
|
||||
{return result1 = a*b%modulus;}
|
||||
|
||||
const Integer& Square(const Integer &a) const
|
||||
{return result1 = a.Squared()%modulus;}
|
||||
|
||||
bool IsUnit(const Integer &a) const
|
||||
{return Integer::Gcd(a, modulus).IsUnit();}
|
||||
|
||||
const Integer& MultiplicativeInverse(const Integer &a) const
|
||||
{return result1 = a.InverseMod(modulus);}
|
||||
|
||||
const Integer& Divide(const Integer &a, const Integer &b) const
|
||||
{return Multiply(a, MultiplicativeInverse(b));}
|
||||
|
||||
Integer CascadeExponentiate(const Integer &x, const Integer &e1,
|
||||
const Integer &y, const Integer &e2) const;
|
||||
|
||||
void SimultaneousExponentiate(Element *results, const Element &base,
|
||||
const Integer *exponents, unsigned int exponentsCount) const;
|
||||
|
||||
unsigned int MaxElementBitLength() const
|
||||
{return (modulus-1).BitCount();}
|
||||
|
||||
unsigned int MaxElementByteLength() const
|
||||
{return (modulus-1).ByteCount();}
|
||||
|
||||
|
||||
static const RandomizationParameter DefaultRandomizationParameter;
|
||||
|
||||
protected:
|
||||
Integer modulus;
|
||||
mutable Integer result, result1;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//! do modular arithmetics in Montgomery representation for increased speed
|
||||
class MontgomeryRepresentation : public ModularArithmetic
|
||||
{
|
||||
public:
|
||||
MontgomeryRepresentation(const Integer &modulus); // modulus must be odd
|
||||
|
||||
bool IsMontgomeryRepresentation() const {return true;}
|
||||
|
||||
Integer ConvertIn(const Integer &a) const
|
||||
{return (a<<(WORD_BITS*modulus.reg_.size()))%modulus;}
|
||||
|
||||
Integer ConvertOut(const Integer &a) const;
|
||||
|
||||
const Integer& MultiplicativeIdentity() const
|
||||
{return result1 = Integer::Power2(WORD_BITS*modulus.reg_.size())%modulus;}
|
||||
|
||||
const Integer& Multiply(const Integer &a, const Integer &b) const;
|
||||
|
||||
const Integer& Square(const Integer &a) const;
|
||||
|
||||
const Integer& MultiplicativeInverse(const Integer &a) const;
|
||||
|
||||
Integer CascadeExponentiate(const Integer &x, const Integer &e1,
|
||||
const Integer &y, const Integer &e2) const
|
||||
{return AbstractRing::CascadeExponentiate(x, e1, y, e2);}
|
||||
|
||||
void SimultaneousExponentiate(Element *results, const Element &base,
|
||||
const Integer *exponents, unsigned int exponentsCount) const
|
||||
{AbstractRing::SimultaneousExponentiate(results, base,
|
||||
exponents, exponentsCount);}
|
||||
|
||||
private:
|
||||
Integer u;
|
||||
mutable AlignedWordBlock workspace;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_MODARITH_HPP
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user