1f579bf8eSKris Kennaway /* apps/spkac.c */ 2f579bf8eSKris Kennaway 3f579bf8eSKris Kennaway /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 4f579bf8eSKris Kennaway * project 1999. Based on an original idea by Massimiliano Pala 5f579bf8eSKris Kennaway * (madwolf@openca.org). 6f579bf8eSKris Kennaway */ 7f579bf8eSKris Kennaway /* ==================================================================== 8f579bf8eSKris Kennaway * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 9f579bf8eSKris Kennaway * 10f579bf8eSKris Kennaway * Redistribution and use in source and binary forms, with or without 11f579bf8eSKris Kennaway * modification, are permitted provided that the following conditions 12f579bf8eSKris Kennaway * are met: 13f579bf8eSKris Kennaway * 14f579bf8eSKris Kennaway * 1. Redistributions of source code must retain the above copyright 15f579bf8eSKris Kennaway * notice, this list of conditions and the following disclaimer. 16f579bf8eSKris Kennaway * 17f579bf8eSKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 18f579bf8eSKris Kennaway * notice, this list of conditions and the following disclaimer in 19f579bf8eSKris Kennaway * the documentation and/or other materials provided with the 20f579bf8eSKris Kennaway * distribution. 21f579bf8eSKris Kennaway * 22f579bf8eSKris Kennaway * 3. All advertising materials mentioning features or use of this 23f579bf8eSKris Kennaway * software must display the following acknowledgment: 24f579bf8eSKris Kennaway * "This product includes software developed by the OpenSSL Project 25f579bf8eSKris Kennaway * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 26f579bf8eSKris Kennaway * 27f579bf8eSKris Kennaway * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 28f579bf8eSKris Kennaway * endorse or promote products derived from this software without 29f579bf8eSKris Kennaway * prior written permission. For written permission, please contact 30f579bf8eSKris Kennaway * licensing@OpenSSL.org. 31f579bf8eSKris Kennaway * 32f579bf8eSKris Kennaway * 5. Products derived from this software may not be called "OpenSSL" 33f579bf8eSKris Kennaway * nor may "OpenSSL" appear in their names without prior written 34f579bf8eSKris Kennaway * permission of the OpenSSL Project. 35f579bf8eSKris Kennaway * 36f579bf8eSKris Kennaway * 6. Redistributions of any form whatsoever must retain the following 37f579bf8eSKris Kennaway * acknowledgment: 38f579bf8eSKris Kennaway * "This product includes software developed by the OpenSSL Project 39f579bf8eSKris Kennaway * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 40f579bf8eSKris Kennaway * 41f579bf8eSKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 42f579bf8eSKris Kennaway * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43f579bf8eSKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 44f579bf8eSKris Kennaway * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 45f579bf8eSKris Kennaway * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46f579bf8eSKris Kennaway * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47f579bf8eSKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 48f579bf8eSKris Kennaway * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49f579bf8eSKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 50f579bf8eSKris Kennaway * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51f579bf8eSKris Kennaway * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 52f579bf8eSKris Kennaway * OF THE POSSIBILITY OF SUCH DAMAGE. 53f579bf8eSKris Kennaway * ==================================================================== 54f579bf8eSKris Kennaway * 55f579bf8eSKris Kennaway * This product includes cryptographic software written by Eric Young 56f579bf8eSKris Kennaway * (eay@cryptsoft.com). This product includes software written by Tim 57f579bf8eSKris Kennaway * Hudson (tjh@cryptsoft.com). 58f579bf8eSKris Kennaway * 59f579bf8eSKris Kennaway */ 60f579bf8eSKris Kennaway #include <stdio.h> 61f579bf8eSKris Kennaway #include <stdlib.h> 62f579bf8eSKris Kennaway #include <string.h> 63f579bf8eSKris Kennaway #include <time.h> 64f579bf8eSKris Kennaway #include "apps.h" 65f579bf8eSKris Kennaway #include <openssl/bio.h> 66f579bf8eSKris Kennaway #include <openssl/conf.h> 67f579bf8eSKris Kennaway #include <openssl/err.h> 68f579bf8eSKris Kennaway #include <openssl/evp.h> 69f579bf8eSKris Kennaway #include <openssl/lhash.h> 70f579bf8eSKris Kennaway #include <openssl/x509.h> 71f579bf8eSKris Kennaway #include <openssl/pem.h> 72f579bf8eSKris Kennaway 73f579bf8eSKris Kennaway #undef PROG 74f579bf8eSKris Kennaway #define PROG spkac_main 75f579bf8eSKris Kennaway 76f579bf8eSKris Kennaway /* -in arg - input file - default stdin 77f579bf8eSKris Kennaway * -out arg - output file - default stdout 78f579bf8eSKris Kennaway */ 79f579bf8eSKris Kennaway 80f579bf8eSKris Kennaway int MAIN(int, char **); 81f579bf8eSKris Kennaway 82f579bf8eSKris Kennaway int MAIN(int argc, char **argv) 83f579bf8eSKris Kennaway { 845c87c606SMark Murray ENGINE *e = NULL; 85f579bf8eSKris Kennaway int i,badops=0, ret = 1; 865c87c606SMark Murray BIO *in = NULL,*out = NULL; 87f579bf8eSKris Kennaway int verify=0,noout=0,pubkey=0; 88f579bf8eSKris Kennaway char *infile = NULL,*outfile = NULL,*prog; 89f579bf8eSKris Kennaway char *passargin = NULL, *passin = NULL; 90f579bf8eSKris Kennaway char *spkac = "SPKAC", *spksect = "default", *spkstr = NULL; 91f579bf8eSKris Kennaway char *challenge = NULL, *keyfile = NULL; 925c87c606SMark Murray CONF *conf = NULL; 93f579bf8eSKris Kennaway NETSCAPE_SPKI *spki = NULL; 94f579bf8eSKris Kennaway EVP_PKEY *pkey = NULL; 955c87c606SMark Murray char *engine=NULL; 96f579bf8eSKris Kennaway 97f579bf8eSKris Kennaway apps_startup(); 98f579bf8eSKris Kennaway 99f579bf8eSKris Kennaway if (!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 100f579bf8eSKris Kennaway 1015c87c606SMark Murray if (!load_config(bio_err, NULL)) 1025c87c606SMark Murray goto end; 1035c87c606SMark Murray 104f579bf8eSKris Kennaway prog=argv[0]; 105f579bf8eSKris Kennaway argc--; 106f579bf8eSKris Kennaway argv++; 107f579bf8eSKris Kennaway while (argc >= 1) 108f579bf8eSKris Kennaway { 109f579bf8eSKris Kennaway if (strcmp(*argv,"-in") == 0) 110f579bf8eSKris Kennaway { 111f579bf8eSKris Kennaway if (--argc < 1) goto bad; 112f579bf8eSKris Kennaway infile= *(++argv); 113f579bf8eSKris Kennaway } 114f579bf8eSKris Kennaway else if (strcmp(*argv,"-out") == 0) 115f579bf8eSKris Kennaway { 116f579bf8eSKris Kennaway if (--argc < 1) goto bad; 117f579bf8eSKris Kennaway outfile= *(++argv); 118f579bf8eSKris Kennaway } 119f579bf8eSKris Kennaway else if (strcmp(*argv,"-passin") == 0) 120f579bf8eSKris Kennaway { 121f579bf8eSKris Kennaway if (--argc < 1) goto bad; 122f579bf8eSKris Kennaway passargin= *(++argv); 123f579bf8eSKris Kennaway } 124f579bf8eSKris Kennaway else if (strcmp(*argv,"-key") == 0) 125f579bf8eSKris Kennaway { 126f579bf8eSKris Kennaway if (--argc < 1) goto bad; 127f579bf8eSKris Kennaway keyfile= *(++argv); 128f579bf8eSKris Kennaway } 129f579bf8eSKris Kennaway else if (strcmp(*argv,"-challenge") == 0) 130f579bf8eSKris Kennaway { 131f579bf8eSKris Kennaway if (--argc < 1) goto bad; 132f579bf8eSKris Kennaway challenge= *(++argv); 133f579bf8eSKris Kennaway } 134f579bf8eSKris Kennaway else if (strcmp(*argv,"-spkac") == 0) 135f579bf8eSKris Kennaway { 136f579bf8eSKris Kennaway if (--argc < 1) goto bad; 137f579bf8eSKris Kennaway spkac= *(++argv); 138f579bf8eSKris Kennaway } 139f579bf8eSKris Kennaway else if (strcmp(*argv,"-spksect") == 0) 140f579bf8eSKris Kennaway { 141f579bf8eSKris Kennaway if (--argc < 1) goto bad; 142f579bf8eSKris Kennaway spksect= *(++argv); 143f579bf8eSKris Kennaway } 1445c87c606SMark Murray else if (strcmp(*argv,"-engine") == 0) 1455c87c606SMark Murray { 1465c87c606SMark Murray if (--argc < 1) goto bad; 1475c87c606SMark Murray engine= *(++argv); 1485c87c606SMark Murray } 149f579bf8eSKris Kennaway else if (strcmp(*argv,"-noout") == 0) 150f579bf8eSKris Kennaway noout=1; 151f579bf8eSKris Kennaway else if (strcmp(*argv,"-pubkey") == 0) 152f579bf8eSKris Kennaway pubkey=1; 153f579bf8eSKris Kennaway else if (strcmp(*argv,"-verify") == 0) 154f579bf8eSKris Kennaway verify=1; 155f579bf8eSKris Kennaway else badops = 1; 156f579bf8eSKris Kennaway argc--; 157f579bf8eSKris Kennaway argv++; 158f579bf8eSKris Kennaway } 159f579bf8eSKris Kennaway 160f579bf8eSKris Kennaway if (badops) 161f579bf8eSKris Kennaway { 162f579bf8eSKris Kennaway bad: 163f579bf8eSKris Kennaway BIO_printf(bio_err,"%s [options]\n",prog); 164f579bf8eSKris Kennaway BIO_printf(bio_err,"where options are\n"); 165f579bf8eSKris Kennaway BIO_printf(bio_err," -in arg input file\n"); 166f579bf8eSKris Kennaway BIO_printf(bio_err," -out arg output file\n"); 167f579bf8eSKris Kennaway BIO_printf(bio_err," -key arg create SPKAC using private key\n"); 168f579bf8eSKris Kennaway BIO_printf(bio_err," -passin arg input file pass phrase source\n"); 169f579bf8eSKris Kennaway BIO_printf(bio_err," -challenge arg challenge string\n"); 170f579bf8eSKris Kennaway BIO_printf(bio_err," -spkac arg alternative SPKAC name\n"); 171f579bf8eSKris Kennaway BIO_printf(bio_err," -noout don't print SPKAC\n"); 172f579bf8eSKris Kennaway BIO_printf(bio_err," -pubkey output public key\n"); 173f579bf8eSKris Kennaway BIO_printf(bio_err," -verify verify SPKAC signature\n"); 1745c87c606SMark Murray BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); 175f579bf8eSKris Kennaway goto end; 176f579bf8eSKris Kennaway } 177f579bf8eSKris Kennaway 178f579bf8eSKris Kennaway ERR_load_crypto_strings(); 179f579bf8eSKris Kennaway if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 180f579bf8eSKris Kennaway BIO_printf(bio_err, "Error getting password\n"); 181f579bf8eSKris Kennaway goto end; 182f579bf8eSKris Kennaway } 183f579bf8eSKris Kennaway 1845c87c606SMark Murray e = setup_engine(bio_err, engine, 0); 1855c87c606SMark Murray 186f579bf8eSKris Kennaway if(keyfile) { 1875c87c606SMark Murray pkey = load_key(bio_err, 1885c87c606SMark Murray strcmp(keyfile, "-") ? keyfile : NULL, 1895c87c606SMark Murray FORMAT_PEM, 1, passin, e, "private key"); 190f579bf8eSKris Kennaway if(!pkey) { 191f579bf8eSKris Kennaway goto end; 192f579bf8eSKris Kennaway } 193f579bf8eSKris Kennaway spki = NETSCAPE_SPKI_new(); 194f579bf8eSKris Kennaway if(challenge) ASN1_STRING_set(spki->spkac->challenge, 195f579bf8eSKris Kennaway challenge, strlen(challenge)); 196f579bf8eSKris Kennaway NETSCAPE_SPKI_set_pubkey(spki, pkey); 197f579bf8eSKris Kennaway NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); 198f579bf8eSKris Kennaway spkstr = NETSCAPE_SPKI_b64_encode(spki); 199f579bf8eSKris Kennaway 200f579bf8eSKris Kennaway if (outfile) out = BIO_new_file(outfile, "w"); 201ddd58736SKris Kennaway else { 202ddd58736SKris Kennaway out = BIO_new_fp(stdout, BIO_NOCLOSE); 2035c87c606SMark Murray #ifdef OPENSSL_SYS_VMS 204ddd58736SKris Kennaway { 205ddd58736SKris Kennaway BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 206ddd58736SKris Kennaway out = BIO_push(tmpbio, out); 207ddd58736SKris Kennaway } 208ddd58736SKris Kennaway #endif 209ddd58736SKris Kennaway } 210f579bf8eSKris Kennaway 211f579bf8eSKris Kennaway if(!out) { 212f579bf8eSKris Kennaway BIO_printf(bio_err, "Error opening output file\n"); 213f579bf8eSKris Kennaway ERR_print_errors(bio_err); 214f579bf8eSKris Kennaway goto end; 215f579bf8eSKris Kennaway } 216f579bf8eSKris Kennaway BIO_printf(out, "SPKAC=%s\n", spkstr); 217ddd58736SKris Kennaway OPENSSL_free(spkstr); 218f579bf8eSKris Kennaway ret = 0; 219f579bf8eSKris Kennaway goto end; 220f579bf8eSKris Kennaway } 221f579bf8eSKris Kennaway 222f579bf8eSKris Kennaway 223f579bf8eSKris Kennaway 224f579bf8eSKris Kennaway if (infile) in = BIO_new_file(infile, "r"); 225f579bf8eSKris Kennaway else in = BIO_new_fp(stdin, BIO_NOCLOSE); 226f579bf8eSKris Kennaway 227f579bf8eSKris Kennaway if(!in) { 228f579bf8eSKris Kennaway BIO_printf(bio_err, "Error opening input file\n"); 229f579bf8eSKris Kennaway ERR_print_errors(bio_err); 230f579bf8eSKris Kennaway goto end; 231f579bf8eSKris Kennaway } 232f579bf8eSKris Kennaway 2335c87c606SMark Murray conf = NCONF_new(NULL); 2345c87c606SMark Murray i = NCONF_load_bio(conf, in, NULL); 235f579bf8eSKris Kennaway 2365c87c606SMark Murray if(!i) { 237f579bf8eSKris Kennaway BIO_printf(bio_err, "Error parsing config file\n"); 238f579bf8eSKris Kennaway ERR_print_errors(bio_err); 239f579bf8eSKris Kennaway goto end; 240f579bf8eSKris Kennaway } 241f579bf8eSKris Kennaway 2425c87c606SMark Murray spkstr = NCONF_get_string(conf, spksect, spkac); 243f579bf8eSKris Kennaway 244f579bf8eSKris Kennaway if(!spkstr) { 245f579bf8eSKris Kennaway BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac); 246f579bf8eSKris Kennaway ERR_print_errors(bio_err); 247f579bf8eSKris Kennaway goto end; 248f579bf8eSKris Kennaway } 249f579bf8eSKris Kennaway 250f579bf8eSKris Kennaway spki = NETSCAPE_SPKI_b64_decode(spkstr, -1); 251f579bf8eSKris Kennaway 252f579bf8eSKris Kennaway if(!spki) { 253f579bf8eSKris Kennaway BIO_printf(bio_err, "Error loading SPKAC\n"); 254f579bf8eSKris Kennaway ERR_print_errors(bio_err); 255f579bf8eSKris Kennaway goto end; 256f579bf8eSKris Kennaway } 257f579bf8eSKris Kennaway 258f579bf8eSKris Kennaway if (outfile) out = BIO_new_file(outfile, "w"); 259ddd58736SKris Kennaway else { 260ddd58736SKris Kennaway out = BIO_new_fp(stdout, BIO_NOCLOSE); 2615c87c606SMark Murray #ifdef OPENSSL_SYS_VMS 262ddd58736SKris Kennaway { 263ddd58736SKris Kennaway BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 264ddd58736SKris Kennaway out = BIO_push(tmpbio, out); 265ddd58736SKris Kennaway } 266ddd58736SKris Kennaway #endif 267ddd58736SKris Kennaway } 268f579bf8eSKris Kennaway 269f579bf8eSKris Kennaway if(!out) { 270f579bf8eSKris Kennaway BIO_printf(bio_err, "Error opening output file\n"); 271f579bf8eSKris Kennaway ERR_print_errors(bio_err); 272f579bf8eSKris Kennaway goto end; 273f579bf8eSKris Kennaway } 274f579bf8eSKris Kennaway 275f579bf8eSKris Kennaway if(!noout) NETSCAPE_SPKI_print(out, spki); 276f579bf8eSKris Kennaway pkey = NETSCAPE_SPKI_get_pubkey(spki); 277f579bf8eSKris Kennaway if(verify) { 278f579bf8eSKris Kennaway i = NETSCAPE_SPKI_verify(spki, pkey); 279f579bf8eSKris Kennaway if(i) BIO_printf(bio_err, "Signature OK\n"); 280f579bf8eSKris Kennaway else { 281f579bf8eSKris Kennaway BIO_printf(bio_err, "Signature Failure\n"); 282f579bf8eSKris Kennaway ERR_print_errors(bio_err); 283f579bf8eSKris Kennaway goto end; 284f579bf8eSKris Kennaway } 285f579bf8eSKris Kennaway } 286f579bf8eSKris Kennaway if(pubkey) PEM_write_bio_PUBKEY(out, pkey); 287f579bf8eSKris Kennaway 288f579bf8eSKris Kennaway ret = 0; 289f579bf8eSKris Kennaway 290f579bf8eSKris Kennaway end: 2915c87c606SMark Murray NCONF_free(conf); 292f579bf8eSKris Kennaway NETSCAPE_SPKI_free(spki); 293f579bf8eSKris Kennaway BIO_free(in); 294ddd58736SKris Kennaway BIO_free_all(out); 295f579bf8eSKris Kennaway EVP_PKEY_free(pkey); 296ddd58736SKris Kennaway if(passin) OPENSSL_free(passin); 2975c87c606SMark Murray apps_shutdown(); 2985c87c606SMark Murray OPENSSL_EXIT(ret); 299f579bf8eSKris Kennaway } 300