sess_id.c revision 296465
1/* apps/sess_id.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#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include "apps.h"
63#include <openssl/bio.h>
64#include <openssl/err.h>
65#include <openssl/x509.h>
66#include <openssl/pem.h>
67#include <openssl/ssl.h>
68
69#undef PROG
70#define PROG    sess_id_main
71
72static const char *sess_id_usage[] = {
73    "usage: sess_id args\n",
74    "\n",
75    " -inform arg     - input format - default PEM (DER or PEM)\n",
76    " -outform arg    - output format - default PEM\n",
77    " -in arg         - input file - default stdin\n",
78    " -out arg        - output file - default stdout\n",
79    " -text           - print ssl session id details\n",
80    " -cert           - output certificate \n",
81    " -noout          - no CRL output\n",
82    " -context arg    - set the session ID context\n",
83    NULL
84};
85
86static SSL_SESSION *load_sess_id(char *file, int format);
87
88int MAIN(int, char **);
89
90int MAIN(int argc, char **argv)
91{
92    SSL_SESSION *x = NULL;
93    int ret = 1, i, num, badops = 0;
94    BIO *out = NULL;
95    int informat, outformat;
96    char *infile = NULL, *outfile = NULL, *context = NULL;
97    int cert = 0, noout = 0, text = 0;
98    const char **pp;
99
100    apps_startup();
101
102    if (bio_err == NULL)
103        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
104            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
105
106    informat = FORMAT_PEM;
107    outformat = FORMAT_PEM;
108
109    argc--;
110    argv++;
111    num = 0;
112    while (argc >= 1) {
113        if (strcmp(*argv, "-inform") == 0) {
114            if (--argc < 1)
115                goto bad;
116            informat = str2fmt(*(++argv));
117        } else if (strcmp(*argv, "-outform") == 0) {
118            if (--argc < 1)
119                goto bad;
120            outformat = str2fmt(*(++argv));
121        } else if (strcmp(*argv, "-in") == 0) {
122            if (--argc < 1)
123                goto bad;
124            infile = *(++argv);
125        } else if (strcmp(*argv, "-out") == 0) {
126            if (--argc < 1)
127                goto bad;
128            outfile = *(++argv);
129        } else if (strcmp(*argv, "-text") == 0)
130            text = ++num;
131        else if (strcmp(*argv, "-cert") == 0)
132            cert = ++num;
133        else if (strcmp(*argv, "-noout") == 0)
134            noout = ++num;
135        else if (strcmp(*argv, "-context") == 0) {
136            if (--argc < 1)
137                goto bad;
138            context = *++argv;
139        } else {
140            BIO_printf(bio_err, "unknown option %s\n", *argv);
141            badops = 1;
142            break;
143        }
144        argc--;
145        argv++;
146    }
147
148    if (badops) {
149 bad:
150        for (pp = sess_id_usage; (*pp != NULL); pp++)
151            BIO_printf(bio_err, "%s", *pp);
152        goto end;
153    }
154
155    ERR_load_crypto_strings();
156    x = load_sess_id(infile, informat);
157    if (x == NULL) {
158        goto end;
159    }
160
161    if (context) {
162        x->sid_ctx_length = strlen(context);
163        if (x->sid_ctx_length > SSL_MAX_SID_CTX_LENGTH) {
164            BIO_printf(bio_err, "Context too long\n");
165            goto end;
166        }
167        memcpy(x->sid_ctx, context, x->sid_ctx_length);
168    }
169#ifdef undef
170    /* just testing for memory leaks :-) */
171    {
172        SSL_SESSION *s;
173        char buf[1024 * 10], *p;
174        int i;
175
176        s = SSL_SESSION_new();
177
178        p = &buf;
179        i = i2d_SSL_SESSION(x, &p);
180        p = &buf;
181        d2i_SSL_SESSION(&s, &p, (long)i);
182        p = &buf;
183        d2i_SSL_SESSION(&s, &p, (long)i);
184        p = &buf;
185        d2i_SSL_SESSION(&s, &p, (long)i);
186        SSL_SESSION_free(s);
187    }
188#endif
189
190    if (!noout || text) {
191        out = BIO_new(BIO_s_file());
192        if (out == NULL) {
193            ERR_print_errors(bio_err);
194            goto end;
195        }
196
197        if (outfile == NULL) {
198            BIO_set_fp(out, stdout, BIO_NOCLOSE);
199#ifdef OPENSSL_SYS_VMS
200            {
201                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
202                out = BIO_push(tmpbio, out);
203            }
204#endif
205        } else {
206            if (BIO_write_filename(out, outfile) <= 0) {
207                perror(outfile);
208                goto end;
209            }
210        }
211    }
212
213    if (text) {
214        SSL_SESSION_print(out, x);
215
216        if (cert) {
217            if (x->peer == NULL)
218                BIO_puts(out, "No certificate present\n");
219            else
220                X509_print(out, x->peer);
221        }
222    }
223
224    if (!noout && !cert) {
225        if (outformat == FORMAT_ASN1)
226            i = i2d_SSL_SESSION_bio(out, x);
227        else if (outformat == FORMAT_PEM)
228            i = PEM_write_bio_SSL_SESSION(out, x);
229        else {
230            BIO_printf(bio_err, "bad output format specified for outfile\n");
231            goto end;
232        }
233        if (!i) {
234            BIO_printf(bio_err, "unable to write SSL_SESSION\n");
235            goto end;
236        }
237    } else if (!noout && (x->peer != NULL)) { /* just print the certificate */
238        if (outformat == FORMAT_ASN1)
239            i = (int)i2d_X509_bio(out, x->peer);
240        else if (outformat == FORMAT_PEM)
241            i = PEM_write_bio_X509(out, x->peer);
242        else {
243            BIO_printf(bio_err, "bad output format specified for outfile\n");
244            goto end;
245        }
246        if (!i) {
247            BIO_printf(bio_err, "unable to write X509\n");
248            goto end;
249        }
250    }
251    ret = 0;
252 end:
253    if (out != NULL)
254        BIO_free_all(out);
255    if (x != NULL)
256        SSL_SESSION_free(x);
257    apps_shutdown();
258    OPENSSL_EXIT(ret);
259}
260
261static SSL_SESSION *load_sess_id(char *infile, int format)
262{
263    SSL_SESSION *x = NULL;
264    BIO *in = NULL;
265
266    in = BIO_new(BIO_s_file());
267    if (in == NULL) {
268        ERR_print_errors(bio_err);
269        goto end;
270    }
271
272    if (infile == NULL)
273        BIO_set_fp(in, stdin, BIO_NOCLOSE);
274    else {
275        if (BIO_read_filename(in, infile) <= 0) {
276            perror(infile);
277            goto end;
278        }
279    }
280    if (format == FORMAT_ASN1)
281        x = d2i_SSL_SESSION_bio(in, NULL);
282    else if (format == FORMAT_PEM)
283        x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
284    else {
285        BIO_printf(bio_err, "bad input format specified for input crl\n");
286        goto end;
287    }
288    if (x == NULL) {
289        BIO_printf(bio_err, "unable to load SSL_SESSION\n");
290        ERR_print_errors(bio_err);
291        goto end;
292    }
293
294 end:
295    if (in != NULL)
296        BIO_free(in);
297    return (x);
298}
299