155714Skris/* apps/sess_id.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280304Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280304Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280304Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280304Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280304Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <stdlib.h> 6155714Skris#include <string.h> 6255714Skris#include "apps.h" 6355714Skris#include <openssl/bio.h> 6455714Skris#include <openssl/err.h> 6555714Skris#include <openssl/x509.h> 6655714Skris#include <openssl/pem.h> 6755714Skris#include <openssl/ssl.h> 6855714Skris 6955714Skris#undef PROG 70280304Sjkim#define PROG sess_id_main 7155714Skris 72280304Sjkimstatic const char *sess_id_usage[] = { 73280304Sjkim "usage: sess_id args\n", 74280304Sjkim "\n", 75280304Sjkim " -inform arg - input format - default PEM (DER or PEM)\n", 76280304Sjkim " -outform arg - output format - default PEM\n", 77280304Sjkim " -in arg - input file - default stdin\n", 78280304Sjkim " -out arg - output file - default stdout\n", 79280304Sjkim " -text - print ssl session id details\n", 80280304Sjkim " -cert - output certificate \n", 81280304Sjkim " -noout - no CRL output\n", 82280304Sjkim " -context arg - set the session ID context\n", 83280304Sjkim NULL 8455714Skris}; 8555714Skris 8655714Skrisstatic SSL_SESSION *load_sess_id(char *file, int format); 8759191Skris 8859191Skrisint MAIN(int, char **); 8959191Skris 9055714Skrisint MAIN(int argc, char **argv) 91280304Sjkim{ 92280304Sjkim SSL_SESSION *x = NULL; 93280304Sjkim X509 *peer = NULL; 94280304Sjkim int ret = 1, i, num, badops = 0; 95280304Sjkim BIO *out = NULL; 96280304Sjkim int informat, outformat; 97280304Sjkim char *infile = NULL, *outfile = NULL, *context = NULL; 98280304Sjkim int cert = 0, noout = 0, text = 0; 99280304Sjkim const char **pp; 10055714Skris 101280304Sjkim apps_startup(); 10255714Skris 103280304Sjkim if (bio_err == NULL) 104280304Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 105280304Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 10655714Skris 107280304Sjkim informat = FORMAT_PEM; 108280304Sjkim outformat = FORMAT_PEM; 10955714Skris 110280304Sjkim argc--; 111280304Sjkim argv++; 112280304Sjkim num = 0; 113280304Sjkim while (argc >= 1) { 114280304Sjkim if (strcmp(*argv, "-inform") == 0) { 115280304Sjkim if (--argc < 1) 116280304Sjkim goto bad; 117280304Sjkim informat = str2fmt(*(++argv)); 118280304Sjkim } else if (strcmp(*argv, "-outform") == 0) { 119280304Sjkim if (--argc < 1) 120280304Sjkim goto bad; 121280304Sjkim outformat = str2fmt(*(++argv)); 122280304Sjkim } else if (strcmp(*argv, "-in") == 0) { 123280304Sjkim if (--argc < 1) 124280304Sjkim goto bad; 125280304Sjkim infile = *(++argv); 126280304Sjkim } else if (strcmp(*argv, "-out") == 0) { 127280304Sjkim if (--argc < 1) 128280304Sjkim goto bad; 129280304Sjkim outfile = *(++argv); 130280304Sjkim } else if (strcmp(*argv, "-text") == 0) 131280304Sjkim text = ++num; 132280304Sjkim else if (strcmp(*argv, "-cert") == 0) 133280304Sjkim cert = ++num; 134280304Sjkim else if (strcmp(*argv, "-noout") == 0) 135280304Sjkim noout = ++num; 136280304Sjkim else if (strcmp(*argv, "-context") == 0) { 137280304Sjkim if (--argc < 1) 138280304Sjkim goto bad; 139280304Sjkim context = *++argv; 140280304Sjkim } else { 141280304Sjkim BIO_printf(bio_err, "unknown option %s\n", *argv); 142280304Sjkim badops = 1; 143280304Sjkim break; 144280304Sjkim } 145280304Sjkim argc--; 146280304Sjkim argv++; 147280304Sjkim } 14855714Skris 149280304Sjkim if (badops) { 150280304Sjkim bad: 151280304Sjkim for (pp = sess_id_usage; (*pp != NULL); pp++) 152280304Sjkim BIO_printf(bio_err, "%s", *pp); 153280304Sjkim goto end; 154280304Sjkim } 15555714Skris 156280304Sjkim ERR_load_crypto_strings(); 157280304Sjkim x = load_sess_id(infile, informat); 158280304Sjkim if (x == NULL) { 159280304Sjkim goto end; 160280304Sjkim } 161280304Sjkim peer = SSL_SESSION_get0_peer(x); 16255714Skris 163280304Sjkim if (context) { 164280304Sjkim size_t ctx_len = strlen(context); 165280304Sjkim if (ctx_len > SSL_MAX_SID_CTX_LENGTH) { 166280304Sjkim BIO_printf(bio_err, "Context too long\n"); 167280304Sjkim goto end; 168280304Sjkim } 169280304Sjkim SSL_SESSION_set1_id_context(x, (unsigned char *)context, ctx_len); 170280304Sjkim } 17155714Skris#ifdef undef 172280304Sjkim /* just testing for memory leaks :-) */ 173280304Sjkim { 174280304Sjkim SSL_SESSION *s; 175280304Sjkim char buf[1024 * 10], *p; 176280304Sjkim int i; 17755714Skris 178280304Sjkim s = SSL_SESSION_new(); 17955714Skris 180280304Sjkim p = &buf; 181280304Sjkim i = i2d_SSL_SESSION(x, &p); 182280304Sjkim p = &buf; 183280304Sjkim d2i_SSL_SESSION(&s, &p, (long)i); 184280304Sjkim p = &buf; 185280304Sjkim d2i_SSL_SESSION(&s, &p, (long)i); 186280304Sjkim p = &buf; 187280304Sjkim d2i_SSL_SESSION(&s, &p, (long)i); 188280304Sjkim SSL_SESSION_free(s); 189280304Sjkim } 19055714Skris#endif 19155714Skris 192280304Sjkim if (!noout || text) { 193280304Sjkim out = BIO_new(BIO_s_file()); 194280304Sjkim if (out == NULL) { 195280304Sjkim ERR_print_errors(bio_err); 196280304Sjkim goto end; 197280304Sjkim } 19855714Skris 199280304Sjkim if (outfile == NULL) { 200280304Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE); 201109998Smarkm#ifdef OPENSSL_SYS_VMS 202280304Sjkim { 203280304Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 204280304Sjkim out = BIO_push(tmpbio, out); 205280304Sjkim } 20668651Skris#endif 207280304Sjkim } else { 208280304Sjkim if (BIO_write_filename(out, outfile) <= 0) { 209280304Sjkim perror(outfile); 210280304Sjkim goto end; 211280304Sjkim } 212280304Sjkim } 213280304Sjkim } 21455714Skris 215280304Sjkim if (text) { 216280304Sjkim SSL_SESSION_print(out, x); 21755714Skris 218280304Sjkim if (cert) { 219280304Sjkim if (peer == NULL) 220280304Sjkim BIO_puts(out, "No certificate present\n"); 221280304Sjkim else 222280304Sjkim X509_print(out, peer); 223280304Sjkim } 224280304Sjkim } 22555714Skris 226280304Sjkim if (!noout && !cert) { 227280304Sjkim if (outformat == FORMAT_ASN1) 228280304Sjkim i = i2d_SSL_SESSION_bio(out, x); 229280304Sjkim else if (outformat == FORMAT_PEM) 230280304Sjkim i = PEM_write_bio_SSL_SESSION(out, x); 231280304Sjkim else { 232280304Sjkim BIO_printf(bio_err, "bad output format specified for outfile\n"); 233280304Sjkim goto end; 234280304Sjkim } 235280304Sjkim if (!i) { 236280304Sjkim BIO_printf(bio_err, "unable to write SSL_SESSION\n"); 237280304Sjkim goto end; 238280304Sjkim } 239280304Sjkim } else if (!noout && (peer != NULL)) { /* just print the certificate */ 240280304Sjkim if (outformat == FORMAT_ASN1) 241280304Sjkim i = (int)i2d_X509_bio(out, peer); 242280304Sjkim else if (outformat == FORMAT_PEM) 243280304Sjkim i = PEM_write_bio_X509(out, peer); 244280304Sjkim else { 245280304Sjkim BIO_printf(bio_err, "bad output format specified for outfile\n"); 246280304Sjkim goto end; 247280304Sjkim } 248280304Sjkim if (!i) { 249280304Sjkim BIO_printf(bio_err, "unable to write X509\n"); 250280304Sjkim goto end; 251280304Sjkim } 252280304Sjkim } 253280304Sjkim ret = 0; 254280304Sjkim end: 255280304Sjkim if (out != NULL) 256280304Sjkim BIO_free_all(out); 257280304Sjkim if (x != NULL) 258280304Sjkim SSL_SESSION_free(x); 259280304Sjkim apps_shutdown(); 260280304Sjkim OPENSSL_EXIT(ret); 261280304Sjkim} 26255714Skris 26355714Skrisstatic SSL_SESSION *load_sess_id(char *infile, int format) 264280304Sjkim{ 265280304Sjkim SSL_SESSION *x = NULL; 266280304Sjkim BIO *in = NULL; 26755714Skris 268280304Sjkim in = BIO_new(BIO_s_file()); 269280304Sjkim if (in == NULL) { 270280304Sjkim ERR_print_errors(bio_err); 271280304Sjkim goto end; 272280304Sjkim } 27355714Skris 274280304Sjkim if (infile == NULL) 275280304Sjkim BIO_set_fp(in, stdin, BIO_NOCLOSE); 276280304Sjkim else { 277280304Sjkim if (BIO_read_filename(in, infile) <= 0) { 278280304Sjkim perror(infile); 279280304Sjkim goto end; 280280304Sjkim } 281280304Sjkim } 282280304Sjkim if (format == FORMAT_ASN1) 283280304Sjkim x = d2i_SSL_SESSION_bio(in, NULL); 284280304Sjkim else if (format == FORMAT_PEM) 285280304Sjkim x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); 286280304Sjkim else { 287280304Sjkim BIO_printf(bio_err, "bad input format specified for input crl\n"); 288280304Sjkim goto end; 289280304Sjkim } 290280304Sjkim if (x == NULL) { 291280304Sjkim BIO_printf(bio_err, "unable to load SSL_SESSION\n"); 292280304Sjkim ERR_print_errors(bio_err); 293280304Sjkim goto end; 294280304Sjkim } 29555714Skris 296280304Sjkim end: 297280304Sjkim if (in != NULL) 298280304Sjkim BIO_free(in); 299280304Sjkim return (x); 300280304Sjkim} 301