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