1*b0100c00Stb /* $OpenBSD: sess_id.c,v 1.13 2025/01/02 12:31:44 tb Exp $ */ 2dab3f910Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3dab3f910Sjsing * All rights reserved. 4dab3f910Sjsing * 5dab3f910Sjsing * This package is an SSL implementation written 6dab3f910Sjsing * by Eric Young (eay@cryptsoft.com). 7dab3f910Sjsing * The implementation was written so as to conform with Netscapes SSL. 8dab3f910Sjsing * 9dab3f910Sjsing * This library is free for commercial and non-commercial use as long as 10dab3f910Sjsing * the following conditions are aheared to. The following conditions 11dab3f910Sjsing * apply to all code found in this distribution, be it the RC4, RSA, 12dab3f910Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13dab3f910Sjsing * included with this distribution is covered by the same copyright terms 14dab3f910Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15dab3f910Sjsing * 16dab3f910Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in 17dab3f910Sjsing * the code are not to be removed. 18dab3f910Sjsing * If this package is used in a product, Eric Young should be given attribution 19dab3f910Sjsing * as the author of the parts of the library used. 20dab3f910Sjsing * This can be in the form of a textual message at program startup or 21dab3f910Sjsing * in documentation (online or textual) provided with the package. 22dab3f910Sjsing * 23dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 24dab3f910Sjsing * modification, are permitted provided that the following conditions 25dab3f910Sjsing * are met: 26dab3f910Sjsing * 1. Redistributions of source code must retain the copyright 27dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 28dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 29dab3f910Sjsing * notice, this list of conditions and the following disclaimer in the 30dab3f910Sjsing * documentation and/or other materials provided with the distribution. 31dab3f910Sjsing * 3. All advertising materials mentioning features or use of this software 32dab3f910Sjsing * must display the following acknowledgement: 33dab3f910Sjsing * "This product includes cryptographic software written by 34dab3f910Sjsing * Eric Young (eay@cryptsoft.com)" 35dab3f910Sjsing * The word 'cryptographic' can be left out if the rouines from the library 36dab3f910Sjsing * being used are not cryptographic related :-). 37dab3f910Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from 38dab3f910Sjsing * the apps directory (application code) you must include an acknowledgement: 39dab3f910Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40dab3f910Sjsing * 41dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42dab3f910Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44dab3f910Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45dab3f910Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46dab3f910Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47dab3f910Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49dab3f910Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50dab3f910Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51dab3f910Sjsing * SUCH DAMAGE. 52dab3f910Sjsing * 53dab3f910Sjsing * The licence and distribution terms for any publically available version or 54dab3f910Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 55dab3f910Sjsing * copied and put under another distribution licence 56dab3f910Sjsing * [including the GNU Public Licence.] 57dab3f910Sjsing */ 58dab3f910Sjsing 59dab3f910Sjsing #include <stdio.h> 60dab3f910Sjsing #include <stdlib.h> 61dab3f910Sjsing #include <string.h> 62dab3f910Sjsing 63dab3f910Sjsing #include "apps.h" 64dab3f910Sjsing 65dab3f910Sjsing #include <openssl/bio.h> 66dab3f910Sjsing #include <openssl/err.h> 67dab3f910Sjsing #include <openssl/pem.h> 68dab3f910Sjsing #include <openssl/ssl.h> 69dab3f910Sjsing #include <openssl/x509.h> 70dab3f910Sjsing 71bc6c34e1Sdoug static struct { 72bc6c34e1Sdoug int cert; 73bc6c34e1Sdoug char *context; 74bc6c34e1Sdoug char *infile; 75bc6c34e1Sdoug int informat; 76bc6c34e1Sdoug int noout; 77bc6c34e1Sdoug char *outfile; 78bc6c34e1Sdoug int outformat; 79bc6c34e1Sdoug int text; 80e7718adaStb } cfg; 81bc6c34e1Sdoug 82ea149709Sguenther static const struct option sess_id_options[] = { 83bc6c34e1Sdoug { 84bc6c34e1Sdoug .name = "cert", 85bc6c34e1Sdoug .desc = "Output certificate if present in session", 86bc6c34e1Sdoug .type = OPTION_FLAG, 87e7718adaStb .opt.flag = &cfg.cert, 88bc6c34e1Sdoug }, 89bc6c34e1Sdoug { 90bc6c34e1Sdoug .name = "context", 91bc6c34e1Sdoug .argname = "id", 92bc6c34e1Sdoug .desc = "Set the session ID context for output", 93bc6c34e1Sdoug .type = OPTION_ARG, 94e7718adaStb .opt.arg = &cfg.context, 95bc6c34e1Sdoug }, 96bc6c34e1Sdoug { 97bc6c34e1Sdoug .name = "in", 98bc6c34e1Sdoug .argname = "file", 99bc6c34e1Sdoug .desc = "Input file (default stdin)", 100bc6c34e1Sdoug .type = OPTION_ARG, 101e7718adaStb .opt.arg = &cfg.infile, 102bc6c34e1Sdoug }, 103bc6c34e1Sdoug { 104bc6c34e1Sdoug .name = "inform", 105bc6c34e1Sdoug .argname = "format", 106bc6c34e1Sdoug .desc = "Input format (DER or PEM (default))", 107bc6c34e1Sdoug .type = OPTION_ARG_FORMAT, 108e7718adaStb .opt.value = &cfg.informat, 109bc6c34e1Sdoug }, 110bc6c34e1Sdoug { 111bc6c34e1Sdoug .name = "noout", 112bc6c34e1Sdoug .desc = "Do not output the encoded session info", 113bc6c34e1Sdoug .type = OPTION_FLAG, 114e7718adaStb .opt.flag = &cfg.noout, 115bc6c34e1Sdoug }, 116bc6c34e1Sdoug { 117bc6c34e1Sdoug .name = "out", 118bc6c34e1Sdoug .argname = "file", 119bc6c34e1Sdoug .desc = "Output file (default stdout)", 120bc6c34e1Sdoug .type = OPTION_ARG, 121e7718adaStb .opt.arg = &cfg.outfile, 122bc6c34e1Sdoug }, 123bc6c34e1Sdoug { 124bc6c34e1Sdoug .name = "outform", 125bc6c34e1Sdoug .argname = "format", 126bc6c34e1Sdoug .desc = "Output format (DER or PEM (default))", 127bc6c34e1Sdoug .type = OPTION_ARG_FORMAT, 128e7718adaStb .opt.value = &cfg.outformat, 129bc6c34e1Sdoug }, 130bc6c34e1Sdoug { 131bc6c34e1Sdoug .name = "text", 132bc6c34e1Sdoug .desc = "Print various public or private key components in" 133bc6c34e1Sdoug " plain text", 134bc6c34e1Sdoug .type = OPTION_FLAG, 135e7718adaStb .opt.flag = &cfg.text, 136bc6c34e1Sdoug }, 137bc6c34e1Sdoug { NULL } 138dab3f910Sjsing }; 139dab3f910Sjsing 140bc6c34e1Sdoug static void 141bc6c34e1Sdoug sess_id_usage(void) 142bc6c34e1Sdoug { 143bc6c34e1Sdoug fprintf(stderr, 144bc6c34e1Sdoug "usage: sess_id [-cert] [-context id] [-in file] [-inform fmt] " 145bc6c34e1Sdoug "[-noout]\n" 146bc6c34e1Sdoug " [-out file] [-outform fmt] [-text]\n\n"); 147bc6c34e1Sdoug options_usage(sess_id_options); 148bc6c34e1Sdoug } 149dab3f910Sjsing 150bc6c34e1Sdoug static SSL_SESSION *load_sess_id(char *file, int format); 151dab3f910Sjsing 152dab3f910Sjsing int 153dab3f910Sjsing sess_id_main(int argc, char **argv) 154dab3f910Sjsing { 155dab3f910Sjsing SSL_SESSION *x = NULL; 156dab3f910Sjsing X509 *peer = NULL; 157bc6c34e1Sdoug int ret = 1, i; 158dab3f910Sjsing BIO *out = NULL; 159dab3f910Sjsing 16051811eadSderaadt if (pledge("stdio cpath wpath rpath", NULL) == -1) { 1619bc487adSdoug perror("pledge"); 162e370f0eeSdoug exit(1); 163e370f0eeSdoug } 1649bc487adSdoug 165e7718adaStb memset(&cfg, 0, sizeof(cfg)); 166dab3f910Sjsing 167e7718adaStb cfg.informat = FORMAT_PEM; 168e7718adaStb cfg.outformat = FORMAT_PEM; 169bc6c34e1Sdoug 170bc6c34e1Sdoug if (options_parse(argc, argv, sess_id_options, NULL, NULL) != 0) { 171bc6c34e1Sdoug sess_id_usage(); 172bc6c34e1Sdoug return (1); 173dab3f910Sjsing } 174dab3f910Sjsing 175e7718adaStb x = load_sess_id(cfg.infile, cfg.informat); 176dab3f910Sjsing if (x == NULL) { 177dab3f910Sjsing goto end; 178dab3f910Sjsing } 179dab3f910Sjsing peer = SSL_SESSION_get0_peer(x); 180dab3f910Sjsing 181e7718adaStb if (cfg.context) { 182e7718adaStb size_t ctx_len = strlen(cfg.context); 183dab3f910Sjsing if (ctx_len > SSL_MAX_SID_CTX_LENGTH) { 184dab3f910Sjsing BIO_printf(bio_err, "Context too long\n"); 185dab3f910Sjsing goto end; 186dab3f910Sjsing } 187bc6c34e1Sdoug SSL_SESSION_set1_id_context(x, 188e7718adaStb (unsigned char *)cfg.context, ctx_len); 189dab3f910Sjsing } 190dab3f910Sjsing 191e7718adaStb if (!cfg.noout || cfg.text) { 192dab3f910Sjsing out = BIO_new(BIO_s_file()); 193dab3f910Sjsing if (out == NULL) { 194dab3f910Sjsing ERR_print_errors(bio_err); 195dab3f910Sjsing goto end; 196dab3f910Sjsing } 197e7718adaStb if (cfg.outfile == NULL) { 198dab3f910Sjsing BIO_set_fp(out, stdout, BIO_NOCLOSE); 199dab3f910Sjsing } else { 200e7718adaStb if (BIO_write_filename(out, cfg.outfile) 201bc6c34e1Sdoug <= 0) { 202e7718adaStb perror(cfg.outfile); 203dab3f910Sjsing goto end; 204dab3f910Sjsing } 205dab3f910Sjsing } 206dab3f910Sjsing } 207e7718adaStb if (cfg.text) { 208dab3f910Sjsing SSL_SESSION_print(out, x); 209dab3f910Sjsing 210e7718adaStb if (cfg.cert) { 211dab3f910Sjsing if (peer == NULL) 212dab3f910Sjsing BIO_puts(out, "No certificate present\n"); 213dab3f910Sjsing else 214dab3f910Sjsing X509_print(out, peer); 215dab3f910Sjsing } 216dab3f910Sjsing } 217e7718adaStb if (!cfg.noout && !cfg.cert) { 218e7718adaStb if (cfg.outformat == FORMAT_ASN1) 219dab3f910Sjsing i = i2d_SSL_SESSION_bio(out, x); 220e7718adaStb else if (cfg.outformat == FORMAT_PEM) 221dab3f910Sjsing i = PEM_write_bio_SSL_SESSION(out, x); 222dab3f910Sjsing else { 223bc6c34e1Sdoug BIO_printf(bio_err, 224bc6c34e1Sdoug "bad output format specified for outfile\n"); 225dab3f910Sjsing goto end; 226dab3f910Sjsing } 227dab3f910Sjsing if (!i) { 228dab3f910Sjsing BIO_printf(bio_err, "unable to write SSL_SESSION\n"); 229dab3f910Sjsing goto end; 230dab3f910Sjsing } 231e7718adaStb } else if (!cfg.noout && (peer != NULL)) { 232bc6c34e1Sdoug /* just print the certificate */ 233e7718adaStb if (cfg.outformat == FORMAT_ASN1) 234dab3f910Sjsing i = (int) i2d_X509_bio(out, peer); 235e7718adaStb else if (cfg.outformat == FORMAT_PEM) 236dab3f910Sjsing i = PEM_write_bio_X509(out, peer); 237dab3f910Sjsing else { 238bc6c34e1Sdoug BIO_printf(bio_err, 239bc6c34e1Sdoug "bad output format specified for outfile\n"); 240dab3f910Sjsing goto end; 241dab3f910Sjsing } 242dab3f910Sjsing if (!i) { 243dab3f910Sjsing BIO_printf(bio_err, "unable to write X509\n"); 244dab3f910Sjsing goto end; 245dab3f910Sjsing } 246dab3f910Sjsing } 247dab3f910Sjsing ret = 0; 248bc6c34e1Sdoug 249dab3f910Sjsing end: 250dab3f910Sjsing BIO_free_all(out); 251dab3f910Sjsing SSL_SESSION_free(x); 252dab3f910Sjsing 253dab3f910Sjsing return (ret); 254dab3f910Sjsing } 255dab3f910Sjsing 256dab3f910Sjsing static SSL_SESSION * 257dab3f910Sjsing load_sess_id(char *infile, int format) 258dab3f910Sjsing { 259dab3f910Sjsing SSL_SESSION *x = NULL; 260dab3f910Sjsing BIO *in = NULL; 261dab3f910Sjsing 262dab3f910Sjsing in = BIO_new(BIO_s_file()); 263dab3f910Sjsing if (in == NULL) { 264dab3f910Sjsing ERR_print_errors(bio_err); 265dab3f910Sjsing goto end; 266dab3f910Sjsing } 267dab3f910Sjsing if (infile == NULL) 268dab3f910Sjsing BIO_set_fp(in, stdin, BIO_NOCLOSE); 269dab3f910Sjsing else { 270dab3f910Sjsing if (BIO_read_filename(in, infile) <= 0) { 271dab3f910Sjsing perror(infile); 272dab3f910Sjsing goto end; 273dab3f910Sjsing } 274dab3f910Sjsing } 275dab3f910Sjsing if (format == FORMAT_ASN1) 276dab3f910Sjsing x = d2i_SSL_SESSION_bio(in, NULL); 277dab3f910Sjsing else if (format == FORMAT_PEM) 278dab3f910Sjsing x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); 279dab3f910Sjsing else { 280bc6c34e1Sdoug BIO_printf(bio_err, 281bc6c34e1Sdoug "bad input format specified for input crl\n"); 282dab3f910Sjsing goto end; 283dab3f910Sjsing } 284dab3f910Sjsing if (x == NULL) { 285dab3f910Sjsing BIO_printf(bio_err, "unable to load SSL_SESSION\n"); 286dab3f910Sjsing ERR_print_errors(bio_err); 287dab3f910Sjsing goto end; 288dab3f910Sjsing } 289dab3f910Sjsing end: 290dab3f910Sjsing BIO_free(in); 291dab3f910Sjsing return (x); 292dab3f910Sjsing } 293