~ubuntu-branches/ubuntu/oneiric/likewise-open/oneiric

« back to all changes in this revision

Viewing changes to openssl/apps/openssl.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Salley
  • Date: 2010-11-22 12:06:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122120600-8lba1fpceot71wlb
Tags: 6.0.0.53010-1
Likewise Open 6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* apps/openssl.c */
 
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 
3
 * All rights reserved.
 
4
 *
 
5
 * This package is an SSL implementation written
 
6
 * by Eric Young (eay@cryptsoft.com).
 
7
 * The implementation was written so as to conform with Netscapes SSL.
 
8
 * 
 
9
 * This library is free for commercial and non-commercial use as long as
 
10
 * the following conditions are aheared to.  The following conditions
 
11
 * apply to all code found in this distribution, be it the RC4, RSA,
 
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 
13
 * included with this distribution is covered by the same copyright terms
 
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 
15
 * 
 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
 
17
 * the code are not to be removed.
 
18
 * If this package is used in a product, Eric Young should be given attribution
 
19
 * as the author of the parts of the library used.
 
20
 * This can be in the form of a textual message at program startup or
 
21
 * in documentation (online or textual) provided with the package.
 
22
 * 
 
23
 * Redistribution and use in source and binary forms, with or without
 
24
 * modification, are permitted provided that the following conditions
 
25
 * are met:
 
26
 * 1. Redistributions of source code must retain the copyright
 
27
 *    notice, this list of conditions and the following disclaimer.
 
28
 * 2. Redistributions in binary form must reproduce the above copyright
 
29
 *    notice, this list of conditions and the following disclaimer in the
 
30
 *    documentation and/or other materials provided with the distribution.
 
31
 * 3. All advertising materials mentioning features or use of this software
 
32
 *    must display the following acknowledgement:
 
33
 *    "This product includes cryptographic software written by
 
34
 *     Eric Young (eay@cryptsoft.com)"
 
35
 *    The word 'cryptographic' can be left out if the rouines from the library
 
36
 *    being used are not cryptographic related :-).
 
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 
38
 *    the apps directory (application code) you must include an acknowledgement:
 
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 
40
 * 
 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
51
 * SUCH DAMAGE.
 
52
 * 
 
53
 * The licence and distribution terms for any publically available version or
 
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 
55
 * copied and put under another distribution licence
 
56
 * [including the GNU Public Licence.]
 
57
 */
 
58
/* ====================================================================
 
59
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
 
60
 *
 
61
 * Redistribution and use in source and binary forms, with or without
 
62
 * modification, are permitted provided that the following conditions
 
63
 * are met:
 
64
 *
 
65
 * 1. Redistributions of source code must retain the above copyright
 
66
 *    notice, this list of conditions and the following disclaimer. 
 
67
 *
 
68
 * 2. Redistributions in binary form must reproduce the above copyright
 
69
 *    notice, this list of conditions and the following disclaimer in
 
70
 *    the documentation and/or other materials provided with the
 
71
 *    distribution.
 
72
 *
 
73
 * 3. All advertising materials mentioning features or use of this
 
74
 *    software must display the following acknowledgment:
 
75
 *    "This product includes software developed by the OpenSSL Project
 
76
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 
77
 *
 
78
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 
79
 *    endorse or promote products derived from this software without
 
80
 *    prior written permission. For written permission, please contact
 
81
 *    openssl-core@openssl.org.
 
82
 *
 
83
 * 5. Products derived from this software may not be called "OpenSSL"
 
84
 *    nor may "OpenSSL" appear in their names without prior written
 
85
 *    permission of the OpenSSL Project.
 
86
 *
 
87
 * 6. Redistributions of any form whatsoever must retain the following
 
88
 *    acknowledgment:
 
89
 *    "This product includes software developed by the OpenSSL Project
 
90
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 
91
 *
 
92
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 
93
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
94
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
95
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 
96
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
97
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
98
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
99
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
100
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
101
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
102
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 
103
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 
104
 * ====================================================================
 
105
 *
 
106
 * This product includes cryptographic software written by Eric Young
 
107
 * (eay@cryptsoft.com).  This product includes software written by Tim
 
108
 * Hudson (tjh@cryptsoft.com).
 
109
 *
 
110
 */
 
111
 
 
112
 
 
113
#include <stdio.h>
 
114
#include <string.h>
 
115
#include <stdlib.h>
 
116
#define OPENSSL_C /* tells apps.h to use complete apps_startup() */
 
117
#include "apps.h"
 
118
#include <openssl/bio.h>
 
119
#include <openssl/crypto.h>
 
120
#include <openssl/lhash.h>
 
121
#include <openssl/conf.h>
 
122
#include <openssl/x509.h>
 
123
#include <openssl/pem.h>
 
124
#include <openssl/ssl.h>
 
125
#ifndef OPENSSL_NO_ENGINE
 
126
#include <openssl/engine.h>
 
127
#endif
 
128
#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
 
129
#include "progs.h"
 
130
#include "s_apps.h"
 
131
#include <openssl/err.h>
 
132
 
 
133
/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
 
134
 * base prototypes (we cast each variable inside the function to the required
 
135
 * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
 
136
 * functions. */
 
137
 
 
138
/* static unsigned long MS_CALLBACK hash(FUNCTION *a); */
 
139
static unsigned long MS_CALLBACK hash(const void *a_void);
 
140
/* static int MS_CALLBACK cmp(FUNCTION *a,FUNCTION *b); */
 
141
static int MS_CALLBACK cmp(const void *a_void,const void *b_void);
 
142
static LHASH *prog_init(void );
 
143
static int do_cmd(LHASH *prog,int argc,char *argv[]);
 
144
char *default_config_file=NULL;
 
145
 
 
146
/* Make sure there is only one when MONOLITH is defined */
 
147
#ifdef MONOLITH
 
148
CONF *config=NULL;
 
149
BIO *bio_err=NULL;
 
150
#endif
 
151
 
 
152
 
 
153
static void lock_dbg_cb(int mode, int type, const char *file, int line)
 
154
        {
 
155
        static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
 
156
        const char *errstr = NULL;
 
157
        int rw;
 
158
        
 
159
        rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
 
160
        if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
 
161
                {
 
162
                errstr = "invalid mode";
 
163
                goto err;
 
164
                }
 
165
 
 
166
        if (type < 0 || type >= CRYPTO_NUM_LOCKS)
 
167
                {
 
168
                errstr = "type out of bounds";
 
169
                goto err;
 
170
                }
 
171
 
 
172
        if (mode & CRYPTO_LOCK)
 
173
                {
 
174
                if (modes[type])
 
175
                        {
 
176
                        errstr = "already locked";
 
177
                        /* must not happen in a single-threaded program
 
178
                         * (would deadlock) */
 
179
                        goto err;
 
180
                        }
 
181
 
 
182
                modes[type] = rw;
 
183
                }
 
184
        else if (mode & CRYPTO_UNLOCK)
 
185
                {
 
186
                if (!modes[type])
 
187
                        {
 
188
                        errstr = "not locked";
 
189
                        goto err;
 
190
                        }
 
191
                
 
192
                if (modes[type] != rw)
 
193
                        {
 
194
                        errstr = (rw == CRYPTO_READ) ?
 
195
                                "CRYPTO_r_unlock on write lock" :
 
196
                                "CRYPTO_w_unlock on read lock";
 
197
                        }
 
198
 
 
199
                modes[type] = 0;
 
200
                }
 
201
        else
 
202
                {
 
203
                errstr = "invalid mode";
 
204
                goto err;
 
205
                }
 
206
 
 
207
 err:
 
208
        if (errstr)
 
209
                {
 
210
                /* we cannot use bio_err here */
 
211
                fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
 
212
                        errstr, mode, type, file, line);
 
213
                }
 
214
        }
 
215
 
 
216
 
 
217
int main(int Argc, char *Argv[])
 
218
        {
 
219
        ARGS arg;
 
220
#define PROG_NAME_SIZE  39
 
221
        char pname[PROG_NAME_SIZE+1];
 
222
        FUNCTION f,*fp;
 
223
        MS_STATIC const char *prompt;
 
224
        MS_STATIC char buf[1024];
 
225
        char *to_free=NULL;
 
226
        int n,i,ret=0;
 
227
        int argc;
 
228
        char **argv,*p;
 
229
        LHASH *prog=NULL;
 
230
        long errline;
 
231
 
 
232
        arg.data=NULL;
 
233
        arg.count=0;
 
234
 
 
235
        if (bio_err == NULL)
 
236
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
 
237
                        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
 
238
 
 
239
        if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */
 
240
                {
 
241
                if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))
 
242
                        {
 
243
                        CRYPTO_malloc_debug_init();
 
244
                        CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
 
245
                        }
 
246
                else
 
247
                        {
 
248
                        /* OPENSSL_DEBUG_MEMORY=off */
 
249
                        CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
 
250
                        }
 
251
                }
 
252
        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
 
253
 
 
254
#if 0
 
255
        if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
 
256
#endif
 
257
                {
 
258
                CRYPTO_set_locking_callback(lock_dbg_cb);
 
259
                }
 
260
 
 
261
        apps_startup();
 
262
 
 
263
        /* Lets load up our environment a little */
 
264
        p=getenv("OPENSSL_CONF");
 
265
        if (p == NULL)
 
266
                p=getenv("SSLEAY_CONF");
 
267
        if (p == NULL)
 
268
                p=to_free=make_config_name();
 
269
 
 
270
        default_config_file=p;
 
271
 
 
272
        config=NCONF_new(NULL);
 
273
        i=NCONF_load(config,p,&errline);
 
274
        if (i == 0)
 
275
                {
 
276
                NCONF_free(config);
 
277
                config = NULL;
 
278
                ERR_clear_error();
 
279
                }
 
280
 
 
281
        prog=prog_init();
 
282
 
 
283
        /* first check the program name */
 
284
        program_name(Argv[0],pname,sizeof pname);
 
285
 
 
286
        f.name=pname;
 
287
        fp=(FUNCTION *)lh_retrieve(prog,&f);
 
288
        if (fp != NULL)
 
289
                {
 
290
                Argv[0]=pname;
 
291
                ret=fp->func(Argc,Argv);
 
292
                goto end;
 
293
                }
 
294
 
 
295
        /* ok, now check that there are not arguments, if there are,
 
296
         * run with them, shifting the ssleay off the front */
 
297
        if (Argc != 1)
 
298
                {
 
299
                Argc--;
 
300
                Argv++;
 
301
                ret=do_cmd(prog,Argc,Argv);
 
302
                if (ret < 0) ret=0;
 
303
                goto end;
 
304
                }
 
305
 
 
306
        /* ok, lets enter the old 'OpenSSL>' mode */
 
307
        
 
308
        for (;;)
 
309
                {
 
310
                ret=0;
 
311
                p=buf;
 
312
                n=sizeof buf;
 
313
                i=0;
 
314
                for (;;)
 
315
                        {
 
316
                        p[0]='\0';
 
317
                        if (i++)
 
318
                                prompt=">";
 
319
                        else    prompt="OpenSSL> ";
 
320
                        fputs(prompt,stdout);
 
321
                        fflush(stdout);
 
322
                        fgets(p,n,stdin);
 
323
                        if (p[0] == '\0') goto end;
 
324
                        i=strlen(p);
 
325
                        if (i <= 1) break;
 
326
                        if (p[i-2] != '\\') break;
 
327
                        i-=2;
 
328
                        p+=i;
 
329
                        n-=i;
 
330
                        }
 
331
                if (!chopup_args(&arg,buf,&argc,&argv)) break;
 
332
 
 
333
                ret=do_cmd(prog,argc,argv);
 
334
                if (ret < 0)
 
335
                        {
 
336
                        ret=0;
 
337
                        goto end;
 
338
                        }
 
339
                if (ret != 0)
 
340
                        BIO_printf(bio_err,"error in %s\n",argv[0]);
 
341
                (void)BIO_flush(bio_err);
 
342
                }
 
343
        BIO_printf(bio_err,"bad exit\n");
 
344
        ret=1;
 
345
end:
 
346
        if (to_free)
 
347
                OPENSSL_free(to_free);
 
348
        if (config != NULL)
 
349
                {
 
350
                NCONF_free(config);
 
351
                config=NULL;
 
352
                }
 
353
        if (prog != NULL) lh_free(prog);
 
354
        if (arg.data != NULL) OPENSSL_free(arg.data);
 
355
 
 
356
        apps_shutdown();
 
357
 
 
358
        CRYPTO_mem_leaks(bio_err);
 
359
        if (bio_err != NULL)
 
360
                {
 
361
                BIO_free(bio_err);
 
362
                bio_err=NULL;
 
363
                }
 
364
        OPENSSL_EXIT(ret);
 
365
        }
 
366
 
 
367
#define LIST_STANDARD_COMMANDS "list-standard-commands"
 
368
#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
 
369
#define LIST_CIPHER_COMMANDS "list-cipher-commands"
 
370
 
 
371
static int do_cmd(LHASH *prog, int argc, char *argv[])
 
372
        {
 
373
        FUNCTION f,*fp;
 
374
        int i,ret=1,tp,nl;
 
375
 
 
376
        if ((argc <= 0) || (argv[0] == NULL))
 
377
                { ret=0; goto end; }
 
378
        f.name=argv[0];
 
379
        fp=(FUNCTION *)lh_retrieve(prog,&f);
 
380
        if (fp != NULL)
 
381
                {
 
382
                ret=fp->func(argc,argv);
 
383
                }
 
384
        else if ((strncmp(argv[0],"no-",3)) == 0)
 
385
                {
 
386
                BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
 
387
#ifdef OPENSSL_SYS_VMS
 
388
                {
 
389
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
 
390
                bio_stdout = BIO_push(tmpbio, bio_stdout);
 
391
                }
 
392
#endif
 
393
                f.name=argv[0]+3;
 
394
                ret = (lh_retrieve(prog,&f) != NULL);
 
395
                if (!ret)
 
396
                        BIO_printf(bio_stdout, "%s\n", argv[0]);
 
397
                else
 
398
                        BIO_printf(bio_stdout, "%s\n", argv[0]+3);
 
399
                BIO_free_all(bio_stdout);
 
400
                goto end;
 
401
                }
 
402
        else if ((strcmp(argv[0],"quit") == 0) ||
 
403
                (strcmp(argv[0],"q") == 0) ||
 
404
                (strcmp(argv[0],"exit") == 0) ||
 
405
                (strcmp(argv[0],"bye") == 0))
 
406
                {
 
407
                ret= -1;
 
408
                goto end;
 
409
                }
 
410
        else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) ||
 
411
                (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
 
412
                (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0))
 
413
                {
 
414
                int list_type;
 
415
                BIO *bio_stdout;
 
416
 
 
417
                if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0)
 
418
                        list_type = FUNC_TYPE_GENERAL;
 
419
                else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0)
 
420
                        list_type = FUNC_TYPE_MD;
 
421
                else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
 
422
                        list_type = FUNC_TYPE_CIPHER;
 
423
                bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
 
424
#ifdef OPENSSL_SYS_VMS
 
425
                {
 
426
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
 
427
                bio_stdout = BIO_push(tmpbio, bio_stdout);
 
428
                }
 
429
#endif
 
430
                
 
431
                for (fp=functions; fp->name != NULL; fp++)
 
432
                        if (fp->type == list_type)
 
433
                                BIO_printf(bio_stdout, "%s\n", fp->name);
 
434
                BIO_free_all(bio_stdout);
 
435
                ret=0;
 
436
                goto end;
 
437
                }
 
438
        else
 
439
                {
 
440
                BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n",
 
441
                        argv[0]);
 
442
                BIO_printf(bio_err, "\nStandard commands");
 
443
                i=0;
 
444
                tp=0;
 
445
                for (fp=functions; fp->name != NULL; fp++)
 
446
                        {
 
447
                        nl=0;
 
448
#ifdef OPENSSL_NO_CAMELLIA
 
449
                        if (((i++) % 5) == 0)
 
450
#else
 
451
                        if (((i++) % 4) == 0)
 
452
#endif
 
453
                                {
 
454
                                BIO_printf(bio_err,"\n");
 
455
                                nl=1;
 
456
                                }
 
457
                        if (fp->type != tp)
 
458
                                {
 
459
                                tp=fp->type;
 
460
                                if (!nl) BIO_printf(bio_err,"\n");
 
461
                                if (tp == FUNC_TYPE_MD)
 
462
                                        {
 
463
                                        i=1;
 
464
                                        BIO_printf(bio_err,
 
465
                                                "\nMessage Digest commands (see the `dgst' command for more details)\n");
 
466
                                        }
 
467
                                else if (tp == FUNC_TYPE_CIPHER)
 
468
                                        {
 
469
                                        i=1;
 
470
                                        BIO_printf(bio_err,"\nCipher commands (see the `enc' command for more details)\n");
 
471
                                        }
 
472
                                }
 
473
#ifdef OPENSSL_NO_CAMELLIA
 
474
                        BIO_printf(bio_err,"%-15s",fp->name);
 
475
#else
 
476
                        BIO_printf(bio_err,"%-18s",fp->name);
 
477
#endif
 
478
                        }
 
479
                BIO_printf(bio_err,"\n\n");
 
480
                ret=0;
 
481
                }
 
482
end:
 
483
        return(ret);
 
484
        }
 
485
 
 
486
static int SortFnByName(const void *_f1,const void *_f2)
 
487
    {
 
488
    const FUNCTION *f1=_f1;
 
489
    const FUNCTION *f2=_f2;
 
490
 
 
491
    if(f1->type != f2->type)
 
492
        return f1->type-f2->type;
 
493
    return strcmp(f1->name,f2->name);
 
494
    }
 
495
 
 
496
static LHASH *prog_init(void)
 
497
        {
 
498
        LHASH *ret;
 
499
        FUNCTION *f;
 
500
        size_t i;
 
501
 
 
502
        /* Purely so it looks nice when the user hits ? */
 
503
        for(i=0,f=functions ; f->name != NULL ; ++f,++i)
 
504
            ;
 
505
        qsort(functions,i,sizeof *functions,SortFnByName);
 
506
 
 
507
        if ((ret=lh_new(hash, cmp)) == NULL)
 
508
                return(NULL);
 
509
 
 
510
        for (f=functions; f->name != NULL; f++)
 
511
                lh_insert(ret,f);
 
512
        return(ret);
 
513
        }
 
514
 
 
515
/* static int MS_CALLBACK cmp(FUNCTION *a, FUNCTION *b) */
 
516
static int MS_CALLBACK cmp(const void *a_void, const void *b_void)
 
517
        {
 
518
        return(strncmp(((const FUNCTION *)a_void)->name,
 
519
                        ((const FUNCTION *)b_void)->name,8));
 
520
        }
 
521
 
 
522
/* static unsigned long MS_CALLBACK hash(FUNCTION *a) */
 
523
static unsigned long MS_CALLBACK hash(const void *a_void)
 
524
        {
 
525
        return(lh_strhash(((const FUNCTION *)a_void)->name));
 
526
        }