added mysql source for win build

--HG--
branch : trunk
This commit is contained in:
Rat
2010-06-20 17:13:10 +02:00
parent fc0dc9556d
commit e0a5d00116
372 changed files with 206887 additions and 0 deletions
+2583
View File
File diff suppressed because it is too large Load Diff
+726
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+24
View File
@@ -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
View File
@@ -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);
}
}
+13
View File
@@ -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
+87
View File
@@ -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
View File
@@ -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[];
+104
View File
@@ -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},
};
+246
View File
@@ -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);
}
File diff suppressed because it is too large Load Diff
+509
View File
@@ -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&REG_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&REG_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&REG_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)&REG_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&REG_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
View File
@@ -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
File diff suppressed because it is too large Load Diff
+116
View File
@@ -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&REG_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
View File
@@ -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
View File
@@ -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&REG_LARGE))
return(smatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
else
return(lmatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags));
}
File diff suppressed because it is too large Load Diff
+38
View File
@@ -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
View File
@@ -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;
}
}
+316
View File
@@ -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
+22
View File
@@ -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
View File
@@ -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
+132
View File
@@ -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
View File
@@ -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/"
+427
View File
@@ -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
View File
@@ -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
+69
View File
@@ -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
View File
@@ -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
View File
@@ -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
+18
View File
@@ -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__ */
+1
View File
@@ -0,0 +1 @@
/* des.h for openssl */
@@ -0,0 +1 @@
/* des_old.h for openvn */
+5
View File
@@ -0,0 +1,5 @@
/* engine.h for libcurl */
#undef HAVE_OPENSSL_ENGINE_H
+8
View File
@@ -0,0 +1,8 @@
/* err.h for openssl */
#ifndef yaSSL_err_h__
#define yaSSL_err_h__
#endif /* yaSSL_err_h__ */
+10
View File
@@ -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");
+1
View File
@@ -0,0 +1 @@
/* hmac.h for openvpn */
+2
View File
@@ -0,0 +1,2 @@
/* lhash.h for openSSL */
+1
View File
@@ -0,0 +1 @@
/* md4.h for libcurl */
+4
View File
@@ -0,0 +1,4 @@
/* md5.h for openssl */
#include "ssl.h" /* in there for now */
@@ -0,0 +1 @@
/* objects.h for openvpn */
+12
View File
@@ -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__ */
+1
View File
@@ -0,0 +1 @@
/* pem.h for libcurl */
+5
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
/* rand.h for openSSL */
+10
View File
@@ -0,0 +1,10 @@
/* rsa.h for openSSL */
#ifndef yaSSL_rsa_h__
#define yaSSL_rsa_h__
enum { RSA_F4 = 1 };
#endif /* yaSSL_rsa_h__ */
+1
View File
@@ -0,0 +1 @@
/* sha.h for openvpn */
+554
View File
@@ -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__ */
+1
View File
@@ -0,0 +1 @@
/* x509.h for libcurl */
+1
View File
@@ -0,0 +1 @@
/* x509v3.h for libcurl */
+96
View File
@@ -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
View File
@@ -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
View File
@@ -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
+86
View File
@@ -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
View File
@@ -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
View File
@@ -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
+528
View File
@@ -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
View File
@@ -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
View File
@@ -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
File diff suppressed because it is too large Load Diff
+4
View File
@@ -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.
*/
File diff suppressed because it is too large Load Diff
+87
View File
@@ -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
View File
@@ -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
View File
@@ -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
File diff suppressed because it is too large Load Diff
+110
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+98
View File
@@ -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
+58
View File
@@ -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
+372
View File
@@ -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
+206
View File
@@ -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
+130
View File
@@ -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
+86
View File
@@ -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
+126
View File
@@ -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
+88
View File
@@ -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
+123
View File
@@ -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
+110
View File
@@ -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
+138
View File
@@ -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
+64
View File
@@ -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
+62
View File
@@ -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
+70
View File
@@ -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
+886
View File
@@ -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