Exemple #1
0
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL;
    char **args, *infile = NULL, *outfile = NULL;
    char *passargin = NULL, *passargout = NULL;
    BIO *in = NULL, *out = NULL;
    const EVP_CIPHER *cipher = NULL;
    int informat, outformat;
    int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
    EVP_PKEY *pkey = NULL;
    char *passin = NULL, *passout = NULL;
    int badarg = 0;
#ifndef OPENSSL_NO_ENGINE
    char *engine = NULL;
#endif
    int ret = 1;

    if (bio_err == NULL)
        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

    if (!load_config(bio_err, NULL))
        goto end;

    informat = FORMAT_PEM;
    outformat = FORMAT_PEM;

    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    args = argv + 1;
    while (!badarg && *args && *args[0] == '-') {
        if (!strcmp(*args, "-inform")) {
            if (args[1]) {
                args++;
                informat = str2fmt(*args);
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-outform")) {
            if (args[1]) {
                args++;
                outformat = str2fmt(*args);
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-passin")) {
            if (!args[1])
                goto bad;
            passargin = *(++args);
        } else if (!strcmp(*args, "-passout")) {
            if (!args[1])
                goto bad;
            passargout = *(++args);
        }
#ifndef OPENSSL_NO_ENGINE
        else if (strcmp(*args, "-engine") == 0) {
            if (!args[1])
                goto bad;
            engine = *(++args);
        }
#endif
        else if (!strcmp(*args, "-in")) {
            if (args[1]) {
                args++;
                infile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-out")) {
            if (args[1]) {
                args++;
                outfile = *args;
            } else
                badarg = 1;
        } else if (strcmp(*args, "-pubin") == 0) {
            pubin = 1;
            pubout = 1;
            pubtext = 1;
        } else if (strcmp(*args, "-pubout") == 0)
            pubout = 1;
        else if (strcmp(*args, "-text_pub") == 0) {
            pubtext = 1;
            text = 1;
        } else if (strcmp(*args, "-text") == 0)
            text = 1;
        else if (strcmp(*args, "-noout") == 0)
            noout = 1;
        else {
            cipher = EVP_get_cipherbyname(*args + 1);
            if (!cipher) {
                BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1);
                badarg = 1;
            }
        }
        args++;
    }

    if (badarg) {
 bad:
        BIO_printf(bio_err, "Usage pkey [options]\n");
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, "-in file        input file\n");
        BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
        BIO_printf(bio_err,
                   "-passin arg     input file pass phrase source\n");
        BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
        BIO_printf(bio_err, "-out file       output file\n");
        BIO_printf(bio_err,
                   "-passout arg    output file pass phrase source\n");
#ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err,
                   "-engine e       use engine e, possibly a hardware device.\n");
#endif
        return 1;
    }
#ifndef OPENSSL_NO_ENGINE
    e = setup_engine(bio_err, engine, 0);
#endif

    if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
        BIO_printf(bio_err, "Error getting passwords\n");
        goto end;
    }

    if (outfile) {
        if (!(out = BIO_new_file(outfile, "wb"))) {
            BIO_printf(bio_err, "Can't open output file %s\n", outfile);
            goto end;
        }
    } else {
        out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
#endif
    }

    if (pubin)
        pkey = load_pubkey(bio_err, infile, informat, 1,
                           passin, e, "Public Key");
    else
        pkey = load_key(bio_err, infile, informat, 1, passin, e, "key");
    if (!pkey)
        goto end;

printf("GMSSL %s %d\n", __FILE__, __LINE__);

    if (!noout) {
        if (outformat == FORMAT_PEM) {
            if (pubout)
                PEM_write_bio_PUBKEY(out, pkey);
            else
                PEM_write_bio_PrivateKey(out, pkey, cipher,
                                         NULL, 0, NULL, passout);
        } else if (outformat == FORMAT_ASN1) {
            if (pubout)
                i2d_PUBKEY_bio(out, pkey);
            else
                i2d_PrivateKey_bio(out, pkey);
        } else {
            BIO_printf(bio_err, "Bad format specified for key\n");
            goto end;
        }

    }

    if (text) {
        if (pubtext)
            EVP_PKEY_print_public(out, pkey, 0, NULL);
        else
            EVP_PKEY_print_private(out, pkey, 0, NULL);
    }

    ret = 0;

 end:
    EVP_PKEY_free(pkey);
    BIO_free_all(out);
    BIO_free(in);
    if (passin)
        OPENSSL_free(passin);
    if (passout)
        OPENSSL_free(passout);

    return ret;
}
Exemple #2
0
/*
 * Main program for the ssh client.
 */
int
main(int ac, char **av)
{
	int i, r, opt, exit_status, use_syslog;
	char *p, *cp, *line, *argv0, buf[MAXPATHLEN];
	struct stat st;
	struct passwd *pw;
	int dummy, timeout_ms;
	extern int optind, optreset;
	extern char *optarg;
	struct servent *sp;
	Forward fwd;

	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
	sanitise_stdfd();

	__progname = ssh_get_progname(av[0]);
	init_rng();

	/*
	 * Save the original real uid.  It will be needed later (uid-swapping
	 * may clobber the real uid).
	 */
	original_real_uid = getuid();
	original_effective_uid = geteuid();

	/*
	 * Use uid-swapping to give up root privileges for the duration of
	 * option processing.  We will re-instantiate the rights when we are
	 * ready to create the privileged port, and will permanently drop
	 * them when the port has been created (actually, when the connection
	 * has been made, as we may need to create the port several times).
	 */
	PRIV_END;

#ifdef HAVE_SETRLIMIT
	/* If we are installed setuid root be careful to not drop core. */
	if (original_real_uid != original_effective_uid) {
		struct rlimit rlim;
		rlim.rlim_cur = rlim.rlim_max = 0;
		if (setrlimit(RLIMIT_CORE, &rlim) < 0)
			fatal("setrlimit failed: %.100s", strerror(errno));
	}
#endif
	/* Get user data. */
	pw = getpwuid(original_real_uid);
	if (!pw) {
		logit("You don't exist, go away!");
		exit(255);
	}
	/* Take a copy of the returned structure. */
	pw = pwcopy(pw);

	/*
	 * Set our umask to something reasonable, as some files are created
	 * with the default umask.  This will make them world-readable but
	 * writable only by the owner, which is ok for all files for which we
	 * don't set the modes explicitly.
	 */
	umask(022);

	/*
	 * Initialize option structure to indicate that no values have been
	 * set.
	 */
	initialize_options(&options);

	/* Parse command-line arguments. */
	host = NULL;
	use_syslog = 0;
	argv0 = av[0];

 again:
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
	    "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
		switch (opt) {
		case '1':
			options.protocol = SSH_PROTO_1;
			break;
		case '2':
			options.protocol = SSH_PROTO_2;
			break;
		case '4':
			options.address_family = AF_INET;
			break;
		case '6':
			options.address_family = AF_INET6;
			break;
		case 'n':
			stdin_null_flag = 1;
			break;
		case 'f':
			fork_after_authentication_flag = 1;
			stdin_null_flag = 1;
			break;
		case 'x':
			options.forward_x11 = 0;
			break;
		case 'X':
			options.forward_x11 = 1;
			break;
		case 'y':
			use_syslog = 1;
			break;
		case 'Y':
			options.forward_x11 = 1;
			options.forward_x11_trusted = 1;
			break;
		case 'g':
			options.gateway_ports = 1;
			break;
		case 'O':
			if (stdio_forward_host != NULL)
				fatal("Cannot specify multiplexing "
				    "command with -W");
			else if (muxclient_command != 0)
				fatal("Multiplexing command already specified");
			if (strcmp(optarg, "check") == 0)
				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
			else if (strcmp(optarg, "forward") == 0)
				muxclient_command = SSHMUX_COMMAND_FORWARD;
			else if (strcmp(optarg, "exit") == 0)
				muxclient_command = SSHMUX_COMMAND_TERMINATE;
			else
				fatal("Invalid multiplex command.");
			break;
		case 'P':	/* deprecated */
			options.use_privileged_port = 0;
			break;
		case 'a':
			options.forward_agent = 0;
			break;
		case 'A':
			options.forward_agent = 1;
			break;
		case 'k':
			options.gss_deleg_creds = 0;
			break;
		case 'K':
			options.gss_authentication = 1;
			options.gss_deleg_creds = 1;
			break;
		case 'i':
			if (stat(optarg, &st) < 0) {
				fprintf(stderr, "Warning: Identity file %s "
				    "not accessible: %s.\n", optarg,
				    strerror(errno));
				break;
			}
			if (options.num_identity_files >=
			    SSH_MAX_IDENTITY_FILES)
				fatal("Too many identity files specified "
				    "(max %d)", SSH_MAX_IDENTITY_FILES);
			options.identity_files[options.num_identity_files++] =
			    xstrdup(optarg);
			break;
		case 'I':
#ifdef ENABLE_PKCS11
			options.pkcs11_provider = xstrdup(optarg);
#else
			fprintf(stderr, "no support for PKCS#11.\n");
#endif
			break;
		case 't':
			if (tty_flag)
				force_tty_flag = 1;
			tty_flag = 1;
			break;
		case 'v':
			if (debug_flag == 0) {
				debug_flag = 1;
				options.log_level = SYSLOG_LEVEL_DEBUG1;
			} else {
				if (options.log_level < SYSLOG_LEVEL_DEBUG3)
					options.log_level++;
				break;
			}
			/* FALLTHROUGH */
		case 'V':
			fprintf(stderr, "%s, %s\n",
			    SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
			if (opt == 'V')
				exit(0);
			break;
		case 'w':
			if (options.tun_open == -1)
				options.tun_open = SSH_TUNMODE_DEFAULT;
			options.tun_local = a2tun(optarg, &options.tun_remote);
			if (options.tun_local == SSH_TUNID_ERR) {
				fprintf(stderr,
				    "Bad tun device '%s'\n", optarg);
				exit(255);
			}
			break;
		case 'W':
			if (stdio_forward_host != NULL)
				fatal("stdio forward already specified");
			if (muxclient_command != 0)
				fatal("Cannot specify stdio forward with -O");
			if (parse_forward(&fwd, optarg, 1, 0)) {
				stdio_forward_host = fwd.listen_host;
				stdio_forward_port = fwd.listen_port;
				xfree(fwd.connect_host);
			} else {
				fprintf(stderr,
				    "Bad stdio forwarding specification '%s'\n",
				    optarg);
				exit(255);
			}
			no_tty_flag = 1;
			no_shell_flag = 1;
			options.clear_forwardings = 1;
			options.exit_on_forward_failure = 1;
			break;
		case 'q':
			options.log_level = SYSLOG_LEVEL_QUIET;
			break;
		case 'e':
			if (optarg[0] == '^' && optarg[2] == 0 &&
			    (u_char) optarg[1] >= 64 &&
			    (u_char) optarg[1] < 128)
				options.escape_char = (u_char) optarg[1] & 31;
			else if (strlen(optarg) == 1)
				options.escape_char = (u_char) optarg[0];
			else if (strcmp(optarg, "none") == 0)
				options.escape_char = SSH_ESCAPECHAR_NONE;
			else {
				fprintf(stderr, "Bad escape character '%s'.\n",
				    optarg);
				exit(255);
			}
			break;
		case 'c':
			if (ciphers_valid(optarg)) {
				/* SSH2 only */
				options.ciphers = xstrdup(optarg);
				options.cipher = SSH_CIPHER_INVALID;
			} else {
				/* SSH1 only */
				options.cipher = cipher_number(optarg);
				if (options.cipher == -1) {
					fprintf(stderr,
					    "Unknown cipher type '%s'\n",
					    optarg);
					exit(255);
				}
				if (options.cipher == SSH_CIPHER_3DES)
					options.ciphers = "3des-cbc";
				else if (options.cipher == SSH_CIPHER_BLOWFISH)
					options.ciphers = "blowfish-cbc";
				else
					options.ciphers = (char *)-1;
			}
			break;
		case 'm':
			if (mac_valid(optarg))
				options.macs = xstrdup(optarg);
			else {
				fprintf(stderr, "Unknown mac type '%s'\n",
				    optarg);
				exit(255);
			}
			break;
		case 'M':
			if (options.control_master == SSHCTL_MASTER_YES)
				options.control_master = SSHCTL_MASTER_ASK;
			else
				options.control_master = SSHCTL_MASTER_YES;
			break;
		case 'p':
			options.port = a2port(optarg);
			if (options.port <= 0) {
				fprintf(stderr, "Bad port '%s'\n", optarg);
				exit(255);
			}
			break;
		case 'l':
			options.user = optarg;
			break;

		case 'L':
			if (parse_forward(&fwd, optarg, 0, 0))
				add_local_forward(&options, &fwd);
			else {
				fprintf(stderr,
				    "Bad local forwarding specification '%s'\n",
				    optarg);
				exit(255);
			}
			break;

		case 'R':
			if (parse_forward(&fwd, optarg, 0, 1)) {
				add_remote_forward(&options, &fwd);
			} else {
				fprintf(stderr,
				    "Bad remote forwarding specification "
				    "'%s'\n", optarg);
				exit(255);
			}
			break;

		case 'D':
			if (parse_forward(&fwd, optarg, 1, 0)) {
				add_local_forward(&options, &fwd);
			} else {
				fprintf(stderr,
				    "Bad dynamic forwarding specification "
				    "'%s'\n", optarg);
				exit(255);
			}
			break;

		case 'C':
			options.compression = 1;
			break;
		case 'N':
			no_shell_flag = 1;
			no_tty_flag = 1;
			break;
		case 'T':
			no_tty_flag = 1;
			break;
		case 'o':
			dummy = 1;
			line = xstrdup(optarg);
			if (process_config_line(&options, host ? host : "",
			    line, "command-line", 0, &dummy) != 0)
				exit(255);
			xfree(line);
			break;
		case 's':
			subsystem_flag = 1;
			break;
		case 'S':
			if (options.control_path != NULL)
				free(options.control_path);
			options.control_path = xstrdup(optarg);
			break;
		case 'b':
			options.bind_address = optarg;
			break;
		case 'F':
			config = optarg;
			break;
		default:
			usage();
		}
	}

	ac -= optind;
	av += optind;

	if (ac > 0 && !host) {
		if (strrchr(*av, '@')) {
			p = xstrdup(*av);
			cp = strrchr(p, '@');
			if (cp == NULL || cp == p)
				usage();
			options.user = p;
			*cp = '\0';
			host = ++cp;
		} else
			host = *av;
		if (ac > 1) {
			optind = optreset = 1;
			goto again;
		}
		ac--, av++;
	}

	/* Check that we got a host name. */
	if (!host)
		usage();

	SSLeay_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Initialize the command to execute on remote host. */
	buffer_init(&command);

	/*
	 * Save the command to execute on the remote host in a buffer. There
	 * is no limit on the length of the command, except by the maximum
	 * packet size.  Also sets the tty flag if there is no command.
	 */
	if (!ac) {
		/* No command specified - execute shell on a tty. */
		tty_flag = 1;
		if (subsystem_flag) {
			fprintf(stderr,
			    "You must specify a subsystem to invoke.\n");
			usage();
		}
	} else {
		/* A command has been specified.  Store it into the buffer. */
		for (i = 0; i < ac; i++) {
			if (i)
				buffer_append(&command, " ", 1);
			buffer_append(&command, av[i], strlen(av[i]));
		}
	}

	/* Cannot fork to background if no command. */
	if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
	    !no_shell_flag)
		fatal("Cannot fork into background without a command "
		    "to execute.");

	/* Allocate a tty by default if no command specified. */
	if (buffer_len(&command) == 0)
		tty_flag = 1;

	/* Force no tty */
	if (no_tty_flag || muxclient_command != 0)
		tty_flag = 0;
	/* Do not allocate a tty if stdin is not a tty. */
	if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
		if (tty_flag)
			logit("Pseudo-terminal will not be allocated because "
			    "stdin is not a terminal.");
		tty_flag = 0;
	}

	/*
	 * Initialize "log" output.  Since we are the client all output
	 * actually goes to stderr.
	 */
	log_init(argv0,
	    options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
	    SYSLOG_FACILITY_USER, !use_syslog);

	/*
	 * Read per-user configuration file.  Ignore the system wide config
	 * file if the user specifies a config file on the command line.
	 */
	if (config != NULL) {
		if (!read_config_file(config, host, &options, 0))
			fatal("Can't open user config file %.100s: "
			    "%.100s", config, strerror(errno));
	} else {
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
		    _PATH_SSH_USER_CONFFILE);
		if (r > 0 && (size_t)r < sizeof(buf))
			(void)read_config_file(buf, host, &options, 1);

		/* Read systemwide configuration file after use config. */
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
		    &options, 0);
	}

	/* Fill configuration defaults. */
	fill_default_options(&options);

	channel_set_af(options.address_family);

	/* reinit */
	log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);

	seed_rng();

	if (options.user == NULL)
		options.user = xstrdup(pw->pw_name);

	/* Get default port if port has not been set. */
	if (options.port == 0) {
		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
		options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
	}

	if (options.local_command != NULL) {
		char thishost[NI_MAXHOST];

		if (gethostname(thishost, sizeof(thishost)) == -1)
			fatal("gethostname: %s", strerror(errno));
		snprintf(buf, sizeof(buf), "%d", options.port);
		debug3("expanding LocalCommand: %s", options.local_command);
		cp = options.local_command;
		options.local_command = percent_expand(cp, "d", pw->pw_dir,
		    "h", options.hostname? options.hostname : host,
                    "l", thishost, "n", host, "r", options.user, "p", buf,
                    "u", pw->pw_name, (char *)NULL);
		debug3("expanded LocalCommand: %s", options.local_command);
		xfree(cp);
	}

	if (options.hostname != NULL)
		host = options.hostname;

	/* force lowercase for hostkey matching */
	if (options.host_key_alias != NULL) {
		for (p = options.host_key_alias; *p; p++)
			if (isupper(*p))
				*p = (char)tolower(*p);
	}

	if (options.proxy_command != NULL &&
	    strcmp(options.proxy_command, "none") == 0) {
		xfree(options.proxy_command);
		options.proxy_command = NULL;
	}
	if (options.control_path != NULL &&
	    strcmp(options.control_path, "none") == 0) {
		xfree(options.control_path);
		options.control_path = NULL;
	}

	if (options.control_path != NULL) {
		char thishost[NI_MAXHOST];

		if (gethostname(thishost, sizeof(thishost)) == -1)
			fatal("gethostname: %s", strerror(errno));
		snprintf(buf, sizeof(buf), "%d", options.port);
		cp = tilde_expand_filename(options.control_path,
		    original_real_uid);
		xfree(options.control_path);
		options.control_path = percent_expand(cp, "p", buf, "h", host,
		    "r", options.user, "l", thishost, (char *)NULL);
		xfree(cp);
	}
	if (muxclient_command != 0 && options.control_path == NULL)
		fatal("No ControlPath specified for \"-O\" command");
	if (options.control_path != NULL)
		muxclient(options.control_path);

	timeout_ms = options.connection_timeout * 1000;

	/* Open a connection to the remote host. */
	if (ssh_connect(host, &hostaddr, options.port,
	    options.address_family, options.connection_attempts, &timeout_ms,
	    options.tcp_keep_alive, 
#ifdef HAVE_CYGWIN
	    options.use_privileged_port,
#else
	    original_effective_uid == 0 && options.use_privileged_port,
#endif
	    options.proxy_command) != 0)
		exit(255);

	if (timeout_ms > 0)
		debug3("timeout: %d ms remain after connect", timeout_ms);

	/*
	 * If we successfully made the connection, load the host private key
	 * in case we will need it later for combined rsa-rhosts
	 * authentication. This must be done before releasing extra
	 * privileges, because the file is only readable by root.
	 * If we cannot access the private keys, load the public keys
	 * instead and try to execute the ssh-keysign helper instead.
	 */
	sensitive_data.nkeys = 0;
	sensitive_data.keys = NULL;
	sensitive_data.external_keysign = 0;
	if (options.rhosts_rsa_authentication ||
	    options.hostbased_authentication) {
		sensitive_data.nkeys = 3;
		sensitive_data.keys = xcalloc(sensitive_data.nkeys,
		    sizeof(Key));

		PRIV_START;
		sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
		    _PATH_HOST_KEY_FILE, "", NULL, NULL);
		sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
		    _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
		sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
		    _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
		PRIV_END;

		if (options.hostbased_authentication == 1 &&
		    sensitive_data.keys[0] == NULL &&
		    sensitive_data.keys[1] == NULL &&
		    sensitive_data.keys[2] == NULL) {
			sensitive_data.keys[1] = key_load_public(
			    _PATH_HOST_DSA_KEY_FILE, NULL);
			sensitive_data.keys[2] = key_load_public(
			    _PATH_HOST_RSA_KEY_FILE, NULL);
			sensitive_data.external_keysign = 1;
		}
	}
	/*
	 * Get rid of any extra privileges that we may have.  We will no
	 * longer need them.  Also, extra privileges could make it very hard
	 * to read identity files and other non-world-readable files from the
	 * user's home directory if it happens to be on a NFS volume where
	 * root is mapped to nobody.
	 */
	if (original_effective_uid == 0) {
		PRIV_START;
		permanently_set_uid(pw);
	}

	/*
	 * Now that we are back to our own permissions, create ~/.ssh
	 * directory if it doesn't already exist.
	 */
	r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
	    strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
	if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0)
		if (mkdir(buf, 0700) < 0)
			error("Could not create directory '%.200s'.", buf);

	/* load options.identity_files */
	load_public_identity_files();

	/* Expand ~ in known host file names. */
	/* XXX mem-leaks: */
	options.system_hostfile =
	    tilde_expand_filename(options.system_hostfile, original_real_uid);
	options.user_hostfile =
	    tilde_expand_filename(options.user_hostfile, original_real_uid);
	options.system_hostfile2 =
	    tilde_expand_filename(options.system_hostfile2, original_real_uid);
	options.user_hostfile2 =
	    tilde_expand_filename(options.user_hostfile2, original_real_uid);

	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */

	/* Log into the remote system.  Never returns if the login fails. */
	ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
	    pw, timeout_ms);

	/* We no longer need the private host keys.  Clear them now. */
	if (sensitive_data.nkeys != 0) {
		for (i = 0; i < sensitive_data.nkeys; i++) {
			if (sensitive_data.keys[i] != NULL) {
				/* Destroys contents safely */
				debug3("clear hostkey %d", i);
				key_free(sensitive_data.keys[i]);
				sensitive_data.keys[i] = NULL;
			}
		}
		xfree(sensitive_data.keys);
	}
	for (i = 0; i < options.num_identity_files; i++) {
		if (options.identity_files[i]) {
			xfree(options.identity_files[i]);
			options.identity_files[i] = NULL;
		}
		if (options.identity_keys[i]) {
			key_free(options.identity_keys[i]);
			options.identity_keys[i] = NULL;
		}
	}

	exit_status = compat20 ? ssh_session2() : ssh_session();
	packet_close();

	if (options.control_path != NULL && muxserver_sock != -1)
		unlink(options.control_path);

	/*
	 * Send SIGHUP to proxy command if used. We don't wait() in
	 * case it hangs and instead rely on init to reap the child
	 */
	if (proxy_command_pid > 1)
		kill(proxy_command_pid, SIGHUP);

	return exit_status;
}
Exemple #3
0
//-------------------------------------------------------------------------------------
bool KBE_RSA::generateKey(const std::string& pubkeyname, 
						  const std::string& prikeyname, int keySize, int e)
{
	KBE_ASSERT(rsa_public == NULL && rsa_private == NULL);
	
	RSA* rsa = NULL;
    FILE *fp = NULL;

	if ((rsa = RSA_generate_key(keySize, e, NULL, NULL)) == NULL) 
	{
		ERR_load_crypto_strings();
		char err[1024];
		char* errret = ERR_error_string(ERR_get_error(), err);
		ERROR_MSG(fmt::format("KBE_RSA::generateKey: RSA_generate_key error({} : {})\n",
			errret, err));

		return false;
	}

	if (!RSA_check_key(rsa)) 
	{
		ERROR_MSG("KBE_RSA::generateKey: invalid RSA Key.\n");
		RSA_free(rsa);
		return false;
	}

	fp = fopen(prikeyname.c_str(), "w");
	if (!fp) {
		RSA_free(rsa);
		return false;
	}

	if (!PEM_write_RSAPrivateKey(fp, static_cast<RSA*>(rsa), NULL, NULL, 0, 0, NULL)) 
	{
		ERR_load_crypto_strings();
		char err[1024];
		char* errret = ERR_error_string(ERR_get_error(), err);
		ERROR_MSG(fmt::format("KBE_RSA::generateKey: PEM_write_RSAPrivateKey error({} : {})\n",
			errret, err));

		fclose(fp);
		RSA_free(rsa);
		return false;
	}

	fclose(fp);
	fp = fopen(pubkeyname.c_str(), "w");
	if (!fp) {
		RSA_free(rsa);
		return false;
	}

	if (!PEM_write_RSAPublicKey(fp, static_cast<RSA*>(rsa))) 
	{
		ERR_load_crypto_strings();
		char err[1024];
		char* errret = ERR_error_string(ERR_get_error(), err);
		ERROR_MSG(fmt::format("KBE_RSA::generateKey: PEM_write_RSAPublicKey error({} : {})\n",
			errret, err));

		fclose(fp);
		RSA_free(rsa);
		return false;
	}

	INFO_MSG(fmt::format("KBE_RSA::generateKey: RSA key generated. keysize({}) bits.\n", keySize));

	RSA_free(rsa);
	fclose(fp);

	return loadPrivate(prikeyname) && loadPublic(pubkeyname);
}
Exemple #4
0
int main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL, *dout = NULL;
    X509 *rcert = NULL;
    STACK_OF(X509) *recips = NULL;
    CMS_ContentInfo *cms = NULL;
    int ret = 1;

    int flags = CMS_STREAM | CMS_DETACHED;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* Read in recipient certificate */
    tbio = BIO_new_file("signer.pem", "r");

    if (!tbio)
        goto err;

    rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    if (!rcert)
        goto err;

    /* Create recipient STACK and add recipient cert to it */
    recips = sk_X509_new_null();

    if (!recips || !sk_X509_push(recips, rcert))
        goto err;

    /*
     * sk_X509_pop_free will free up recipient STACK and its contents so set
     * rcert to NULL so it isn't freed up twice.
     */
    rcert = NULL;

    /* Open content being encrypted */

    in = BIO_new_file("encr.txt", "r");

    dout = BIO_new_file("smencr.out", "wb");

    if (!in)
        goto err;

    /* encrypt content */
    cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);

    if (!cms)
        goto err;

    out = BIO_new_file("smencr.pem", "w");
    if (!out)
        goto err;

    if (!CMS_final(cms, in, dout, flags))
        goto err;

    /* Write out CMS structure without content */
    if (!PEM_write_bio_CMS(out, cms))
        goto err;

    ret = 0;

 err:

    if (ret) {
        fprintf(stderr, "Error Encrypting Data\n");
        ERR_print_errors_fp(stderr);
    }

    if (cms)
        CMS_ContentInfo_free(cms);
    if (rcert)
        X509_free(rcert);
    if (recips)
        sk_X509_pop_free(recips, X509_free);

    if (in)
        BIO_free(in);
    if (out)
        BIO_free(out);
    if (dout)
        BIO_free(dout);
    if (tbio)
        BIO_free(tbio);

    return ret;

}
int main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL;
    X509 *scert = NULL;
    EVP_PKEY *skey = NULL;
    CMS_ContentInfo *cms = NULL;
    int ret = 1;

    /* For simple S/MIME signing use CMS_DETACHED.
     * On OpenSSL 0.9.9 only:
     * for streaming detached set CMS_DETACHED|CMS_STREAM
     * for streaming non-detached set CMS_STREAM
     */
    int flags = CMS_DETACHED|CMS_STREAM;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* Read in signer certificate and private key */
    tbio = BIO_new_file("signer.pem", "r");

    if (!tbio)
        goto err;

    scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    BIO_reset(tbio);

    skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

    if (!scert || !skey)
        goto err;

    /* Open content being signed */

    in = BIO_new_file("sign.txt", "r");

    if (!in)
        goto err;

    /* Sign content */
    cms = CMS_sign(scert, skey, NULL, in, flags);

    if (!cms)
        goto err;

    out = BIO_new_file("smout.txt", "w");
    if (!out)
        goto err;

    if (!(flags & CMS_STREAM))
        BIO_reset(in);

    /* Write out S/MIME message */
    if (!SMIME_write_CMS(out, cms, in, flags))
        goto err;

    ret = 0;

err:

    if (ret)
    {
        fprintf(stderr, "Error Signing Data\n");
        ERR_print_errors_fp(stderr);
    }

    if (cms)
        CMS_ContentInfo_free(cms);
    if (scert)
        X509_free(scert);
    if (skey)
        EVP_PKEY_free(skey);

    if (in)
        BIO_free(in);
    if (out)
        BIO_free(out);
    if (tbio)
        BIO_free(tbio);

    return ret;

}
Exemple #6
0
int main(int argc, char *argv[])
	{
	BN_CTX *ctx;
	BIO *out=NULL;
	int i,ret;
	unsigned char c;
	BIGNUM *r_mont,*r_mont_const,*r_recp,*r_simple,*a,*b,*m;

	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
	                                       * even check its return value
	                                       * (which we should) */

	ERR_load_BN_strings();

	ctx=BN_CTX_new();
	if (ctx == NULL) EXIT(1);
	r_mont=BN_new();
	r_mont_const=BN_new();
	r_recp=BN_new();
	r_simple=BN_new();
	a=BN_new();
	b=BN_new();
	m=BN_new();
	if (	(r_mont == NULL) || (r_recp == NULL) ||
		(a == NULL) || (b == NULL))
		goto err;

	out=BIO_new(BIO_s_file());

	if (out == NULL) EXIT(1);
	BIO_set_fp(out,stdout,BIO_NOCLOSE);

	for (i=0; i<200; i++)
		{
		RAND_bytes(&c,1);
		c=(c%BN_BITS)-BN_BITS2;
		BN_rand(a,NUM_BITS+c,0,0);

		RAND_bytes(&c,1);
		c=(c%BN_BITS)-BN_BITS2;
		BN_rand(b,NUM_BITS+c,0,0);

		RAND_bytes(&c,1);
		c=(c%BN_BITS)-BN_BITS2;
		BN_rand(m,NUM_BITS+c,0,1);

		BN_mod(a,a,m,ctx);
		BN_mod(b,b,m,ctx);

		ret=BN_mod_exp_mont(r_mont,a,b,m,ctx,NULL);
		if (ret <= 0)
			{
			printf("BN_mod_exp_mont() problems\n");
			ERR_print_errors(out);
			EXIT(1);
			}

		ret=BN_mod_exp_recp(r_recp,a,b,m,ctx);
		if (ret <= 0)
			{
			printf("BN_mod_exp_recp() problems\n");
			ERR_print_errors(out);
			EXIT(1);
			}

		ret=BN_mod_exp_simple(r_simple,a,b,m,ctx);
		if (ret <= 0)
			{
			printf("BN_mod_exp_simple() problems\n");
			ERR_print_errors(out);
			EXIT(1);
			}

		ret=BN_mod_exp_mont_consttime(r_mont_const,a,b,m,ctx,NULL);
		if (ret <= 0)
			{
			printf("BN_mod_exp_mont_consttime() problems\n");
			ERR_print_errors(out);
			EXIT(1);
			}

		if (BN_cmp(r_simple, r_mont) == 0
		    && BN_cmp(r_simple,r_recp) == 0
			&& BN_cmp(r_simple,r_mont_const) == 0)
			{
			printf(".");
			fflush(stdout);
			}
		else
		  	{
			if (BN_cmp(r_simple,r_mont) != 0)
				printf("\nsimple and mont results differ\n");
			if (BN_cmp(r_simple,r_mont_const) != 0)
				printf("\nsimple and mont const time results differ\n");
			if (BN_cmp(r_simple,r_recp) != 0)
				printf("\nsimple and recp results differ\n");

			printf("a (%3d) = ",BN_num_bits(a));   BN_print(out,a);
			printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b);
			printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m);
			printf("\nsimple   =");	BN_print(out,r_simple);
			printf("\nrecp     =");	BN_print(out,r_recp);
			printf("\nmont     ="); BN_print(out,r_mont);
			printf("\nmont_ct  ="); BN_print(out,r_mont_const);
			printf("\n");
			EXIT(1);
			}
		}
	BN_free(r_mont);
	BN_free(r_mont_const);
	BN_free(r_recp);
	BN_free(r_simple);
	BN_free(a);
	BN_free(b);
	BN_free(m);
	BN_CTX_free(ctx);
	ERR_remove_thread_state(NULL);
	CRYPTO_mem_leaks(out);
	BIO_free(out);
	printf("\n");

	if (test_exp_mod_zero() != 0)
		goto err;

	printf("done\n");

	EXIT(0);
err:
	ERR_load_crypto_strings();
	ERR_print_errors(out);
#ifdef OPENSSL_SYS_NETWARE
    printf("ERROR\n");
#endif
	EXIT(1);
	return(1);
	}
Exemple #7
0
struct dyString *bio(char *host, char *url, char *certFile, char *certPath)
/*
This SSL/TLS client example, attempts to retrieve a page from an SSL/TLS web server. 
The I/O routines are identical to those of the unencrypted example in BIO_s_connect(3).
*/
{
struct dyString *dy = dyStringNew(0);
char hostnameProto[256];
char requestLine[4096];

BIO *sbio;
int len;
char tmpbuf[1024];
SSL_CTX *ctx;
SSL *ssl;

SSL_library_init();
ERR_load_crypto_strings();
ERR_load_SSL_strings();
OpenSSL_add_all_algorithms();

/* We would seed the PRNG here if the platform didn't
* do it automatically
*/

ctx = SSL_CTX_new(SSLv23_client_method());
if (certFile || certPath)
    {
    SSL_CTX_load_verify_locations(ctx,certFile,certPath);
#if (OPENSSL_VERSION_NUMBER < 0x0090600fL)
    SSL_CTX_set_verify_depth(ctx,1);
#endif
    }

/* We'd normally set some stuff like the verify paths and
* mode here because as things stand this will connect to
* any server whose certificate is signed by any CA.
*/

sbio = BIO_new_ssl_connect(ctx);

BIO_get_ssl(sbio, &ssl);

if(!ssl) 
    {
    fprintf(stderr, "Can't locate SSL pointer\n");
    return NULL;
    }

/* Don't want any retries */
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

/* We might want to do other things with ssl here */

safef(hostnameProto,sizeof(hostnameProto),"%s:https",host);
BIO_set_conn_hostname(sbio, hostnameProto);

if(BIO_do_connect(sbio) <= 0) 
    {
    fprintf(stderr, "Error connecting to server\n");
    ERR_print_errors_fp(stderr);
    return NULL;
    }

if(BIO_do_handshake(sbio) <= 0) 
    {
    fprintf(stderr, "Error establishing SSL connection\n");
    ERR_print_errors_fp(stderr);
    return NULL;
    }

if (certFile || certPath)
    if (!check_cert(ssl, host))
	return NULL;

/* Could examine ssl here to get connection info */

safef(requestLine,sizeof(requestLine),"GET %s HTTP/1.0\n\n",url);
BIO_puts(sbio, requestLine);
for(;;) 
    {
    len = BIO_read(sbio, tmpbuf, 1024);
    if(len <= 0) break;
    dyStringAppendN(dy, tmpbuf, len);
    }
BIO_free_all(sbio);

return dy;
}
int main(int Argc, char *Argv[])
{
    ARGS arg;
#define PROG_NAME_SIZE  39
    char pname[PROG_NAME_SIZE + 1];
    FUNCTION f, *fp;
    MS_STATIC const char *prompt;
    MS_STATIC char buf[1024];
    char *to_free = NULL;
    int n, i, ret = 0;
    int argc;
    char **argv, *p;
    LHASH *prog = NULL;
    long errline;

    arg.data = NULL;
    arg.count = 0;

    in_FIPS_mode = 0;

    if (getenv("OPENSSL_FIPS")) {
#ifdef OPENSSL_FIPS
        if (!FIPS_mode_set(1)) {
            ERR_load_crypto_strings();
            ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
            EXIT(1);
        }
        in_FIPS_mode = 1;
#else
        fprintf(stderr, "FIPS mode not supported.\n");
        EXIT(1);
#endif
    }

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) { /* if not defined, use
                                                   * compiled-in library
                                                   * defaults */
        if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) {
            CRYPTO_malloc_debug_init();
            CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
        } else {
            /* OPENSSL_DEBUG_MEMORY=off */
            CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
        }
    }
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

#if 0
    if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
#endif
    {
        CRYPTO_set_locking_callback(lock_dbg_cb);
    }

    apps_startup();

    /* Lets load up our environment a little */
    p = getenv("OPENSSL_CONF");
    if (p == NULL)
        p = getenv("SSLEAY_CONF");
    if (p == NULL)
        p = to_free = make_config_name();

    default_config_file = p;

    config = NCONF_new(NULL);
    i = NCONF_load(config, p, &errline);
    if (i == 0) {
        NCONF_free(config);
        config = NULL;
        ERR_clear_error();
    }

    prog = prog_init();

    /* first check the program name */
    program_name(Argv[0], pname, sizeof pname);

    f.name = pname;
    fp = (FUNCTION *) lh_retrieve(prog, &f);
    if (fp != NULL) {
        Argv[0] = pname;
        ret = fp->func(Argc, Argv);
        goto end;
    }

    /*
     * ok, now check that there are not arguments, if there are, run with
     * them, shifting the ssleay off the front
     */
    if (Argc != 1) {
        Argc--;
        Argv++;
        ret = do_cmd(prog, Argc, Argv);
        if (ret < 0)
            ret = 0;
        goto end;
    }

    /* ok, lets enter the old 'OpenSSL>' mode */

    for (;;) {
        ret = 0;
        p = buf;
        n = sizeof buf;
        i = 0;
        for (;;) {
            p[0] = '\0';
            if (i++)
                prompt = ">";
            else
                prompt = "OpenSSL> ";
            fputs(prompt, stdout);
            fflush(stdout);
            if (!fgets(p, n, stdin))
                goto end;
            if (p[0] == '\0')
                goto end;
            i = strlen(p);
            if (i <= 1)
                break;
            if (p[i - 2] != '\\')
                break;
            i -= 2;
            p += i;
            n -= i;
        }
        if (!chopup_args(&arg, buf, &argc, &argv))
            break;

        ret = do_cmd(prog, argc, argv);
        if (ret < 0) {
            ret = 0;
            goto end;
        }
        if (ret != 0)
            BIO_printf(bio_err, "error in %s\n", argv[0]);
        (void)BIO_flush(bio_err);
    }
    BIO_printf(bio_err, "bad exit\n");
    ret = 1;
 end:
    if (to_free)
        OPENSSL_free(to_free);
    if (config != NULL) {
        NCONF_free(config);
        config = NULL;
    }
    if (prog != NULL)
        lh_free(prog);
    if (arg.data != NULL)
        OPENSSL_free(arg.data);

    apps_shutdown();

    CRYPTO_mem_leaks(bio_err);
    if (bio_err != NULL) {
        BIO_free(bio_err);
        bio_err = NULL;
    }
    OPENSSL_EXIT(ret);
}
int
dh_main(int argc, char **argv)
{
	DH *dh = NULL;
	int i, badops = 0, text = 0;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, check = 0, noout = 0, C = 0, ret = 1;
	char *infile, *outfile, *prog;
#ifndef OPENSSL_NO_ENGINE
	char *engine;
#endif

	if (!load_config(bio_err, NULL))
		goto end;

#ifndef OPENSSL_NO_ENGINE
	engine = NULL;
#endif
	infile = NULL;
	outfile = NULL;
	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		}
#endif
		else if (strcmp(*argv, "-check") == 0)
			check = 1;
		else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg   input format - one of DER PEM\n");
		BIO_printf(bio_err, " -outform arg  output format - one of DER PEM\n");
		BIO_printf(bio_err, " -in arg       input file\n");
		BIO_printf(bio_err, " -out arg      output file\n");
		BIO_printf(bio_err, " -check        check the DH parameters\n");
		BIO_printf(bio_err, " -text         print a text form of the DH parameters\n");
		BIO_printf(bio_err, " -C            Output C code\n");
		BIO_printf(bio_err, " -noout        no output\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, " -engine e     use engine e, possibly a hardware device.\n");
#endif
		goto end;
	}
	ERR_load_crypto_strings();

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

	if (informat == FORMAT_ASN1)
		dh = d2i_DHparams_bio(in, NULL);
	else if (informat == FORMAT_PEM)
		dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
	else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}
	if (dh == NULL) {
		BIO_printf(bio_err, "unable to load DH parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (text) {
		DHparams_print(out, dh);
#ifdef undef
		printf("p=");
		BN_print(stdout, dh->p);
		printf("\ng=");
		BN_print(stdout, dh->g);
		printf("\n");
		if (dh->length != 0)
			printf("recommended private length=%ld\n", dh->length);
#endif
	}
	if (check) {
		if (!DH_check(dh, &i)) {
			ERR_print_errors(bio_err);
			goto end;
		}
		if (i & DH_CHECK_P_NOT_PRIME)
			printf("p value is not prime\n");
		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
			printf("p value is not a safe prime\n");
		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
			printf("unable to check the generator value\n");
		if (i & DH_NOT_SUITABLE_GENERATOR)
			printf("the g value is not a generator\n");
		if (i == 0)
			printf("DH parameters appear to be ok.\n");
	}
	if (C) {
		unsigned char *data;
		int len, l, bits;

		len = BN_num_bytes(dh->p);
		bits = BN_num_bits(dh->p);
		data = malloc(len);
		if (data == NULL) {
			perror("malloc");
			goto end;
		}
		l = BN_bn2bin(dh->p, data);
		printf("static unsigned char dh%d_p[] = {", bits);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dh->g, data);
		printf("static unsigned char dh%d_g[] = {", bits);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n\n");

		printf("DH *get_dh%d()\n\t{\n", bits);
		printf("\tDH *dh;\n\n");
		printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n");
		printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n",
		    bits, bits);
		printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n",
		    bits, bits);
		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
		printf("\t\treturn(NULL);\n");
		printf("\treturn(dh);\n\t}\n");
		free(data);
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_DHparams_bio(out, dh);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_DHparams(out, dh);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write DH parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	ret = 0;

end:
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (dh != NULL)
		DH_free(dh);
	
	return (ret);
}
Exemple #10
0
int main(int argc, char *argv[])
	{	
	BN_CTX *ctx = NULL;
	BIGNUM *p, *a, *b;
	EC_GROUP *group;
	EC_GROUP *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
	EC_POINT *P, *Q, *R;
	BIGNUM *x, *y, *z;
	unsigned char buf[100];
	size_t i, len;
	int k;
	
	/* enable memory leak checking unless explicitly disabled */
	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
		{
		CRYPTO_malloc_debug_init();
		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
		}
	else
		{
		/* OPENSSL_DEBUG_MEMORY=off */
		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
		}
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
	ERR_load_crypto_strings();

#if 1 /* optional */
	ctx = BN_CTX_new();
	if (!ctx) ABORT;
#endif

	p = BN_new();
	a = BN_new();
	b = BN_new();
	if (!p || !a || !b) ABORT;

	if (!BN_hex2bn(&p, "17")) ABORT;
	if (!BN_hex2bn(&a, "1")) ABORT;
	if (!BN_hex2bn(&b, "1")) ABORT;
	
	group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
	                                             * so that the library gets to choose the EC_METHOD */
	if (!group) ABORT;

	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	{
		EC_GROUP *tmp;
		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
		if (!tmp) ABORT;
		if (!EC_GROUP_copy(tmp, group));
		EC_GROUP_free(group);
		group = tmp;
	}
	
	if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;

	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
	BN_print_fp(stdout, p);
	fprintf(stdout, ")\n     a = 0x");
	BN_print_fp(stdout, a);
	fprintf(stdout, "\n     b = 0x");
	BN_print_fp(stdout, b);
	fprintf(stdout, "\n");

	P = EC_POINT_new(group);
	Q = EC_POINT_new(group);
	R = EC_POINT_new(group);
	if (!P || !Q || !R) ABORT;
	
	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	buf[0] = 0;
	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;

	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	x = BN_new();
	y = BN_new();
	z = BN_new();
	if (!x || !y || !z) ABORT;

	if (!BN_hex2bn(&x, "D")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, Q, ctx))
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
		fprintf(stderr, "Point is not on curve: x = 0x");
		BN_print_fp(stderr, x);
		fprintf(stderr, ", y = 0x");
		BN_print_fp(stderr, y);
		fprintf(stderr, "\n");
		ABORT;
		}

	fprintf(stdout, "A cyclic subgroup:\n");
	k = 100;
	do
		{
		if (k-- == 0) ABORT;

		if (EC_POINT_is_at_infinity(group, P))
			fprintf(stdout, "     point at infinity\n");
		else
			{
			if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;

			fprintf(stdout, "     x = 0x");
			BN_print_fp(stdout, x);
			fprintf(stdout, ", y = 0x");
			BN_print_fp(stdout, y);
			fprintf(stdout, "\n");
			}
		
		if (!EC_POINT_copy(R, P)) ABORT;
		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;

#if 0 /* optional */
		{
			EC_POINT *points[3];
		
			points[0] = R;
			points[1] = Q;
			points[2] = P;
			if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
		}
#endif

		}
	while (!EC_POINT_is_at_infinity(group, P));

	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "Generator as octect string, compressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "\nGenerator as octect string, hybrid form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
	if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
	fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, ", Y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, ", Z = 0x");
	BN_print_fp(stdout, z);
	fprintf(stdout, "\n");

	if (!EC_POINT_invert(group, P, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;


	/* Curve P-192 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
	if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-192 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_192, group)) ABORT;


	/* Curve P-224 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
	if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
	if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-224 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_224, group)) ABORT;


	/* Curve P-256 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
	if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
		"84F3B9CAC2FC632551")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-256 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_256, group)) ABORT;


	/* Curve P-384 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
	if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
		"120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
		"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-384 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
		"7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_384, group)) ABORT;


	/* Curve P-521 (FIPS PUB 186-2, App. 6) */
	
	if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
	if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
	if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
	if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
		"315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
		"DF883D2C34F1EF451FD46B503F00")) ABORT;
	if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;

	if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
		"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
		"3C1856A429BF97E7E31C2E5BD66")) ABORT;
	if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
		"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
		"C9B8899C47AEBB6FB71E91386409")) ABORT;
	if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;

	if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
	fprintf(stdout, "\nNIST curve P-521 -- Generator:\n     x = 0x");
	BN_print_fp(stdout, x);
	fprintf(stdout, "\n     y = 0x");
	BN_print_fp(stdout, y);
	fprintf(stdout, "\n");
	/* G_y value taken from the standard: */
	if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
		"B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
		"7086A272C24088BE94769FD16650")) ABORT;
	if (0 != BN_cmp(y, z)) ABORT;
	
	fprintf(stdout, "verify group order ...");
	fflush(stdout);
	if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, ".");
	fflush(stdout);
	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
	fprintf(stdout, " ok\n");

	if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
	if (!EC_GROUP_copy(P_521, group)) ABORT;


	/* more tests using the last curve */

	if (!EC_POINT_copy(Q, P)) ABORT;
	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */

	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */

	{
		const EC_POINT *points[3];
		const BIGNUM *scalars[3];
	
		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
		points[0] = Q;
		points[1] = Q;
		points[2] = Q;

		if (!BN_add(y, z, BN_value_one())) ABORT;
		if (BN_is_odd(y)) ABORT;
		if (!BN_rshift1(y, y)) ABORT;
		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
		scalars[1] = y;

		fprintf(stdout, "combined multiplication ...");
		fflush(stdout);

		/* z is still the group order */
		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;

		fprintf(stdout, ".");
		fflush(stdout);

		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
		if (!BN_add(z, z, y)) ABORT;
		z->neg = 1;
		scalars[0] = y;
		scalars[1] = z; /* z = -(order + y) */

		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
		if (!EC_POINT_is_at_infinity(group, P)) ABORT;

		fprintf(stdout, ".");
		fflush(stdout);

		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
		if (!BN_add(z, x, y)) ABORT;
		z->neg = 1;
		scalars[0] = x;
		scalars[1] = y;
		scalars[2] = z; /* z = -(x+y) */

		if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
		if (!EC_POINT_is_at_infinity(group, P)) ABORT;

		fprintf(stdout, " ok\n\n");
	}


#if 0
	timings(P_192, 0, ctx);
	timings(P_192, 1, ctx);
	timings(P_224, 0, ctx);
	timings(P_224, 1, ctx);
	timings(P_256, 0, ctx);
	timings(P_256, 1, ctx);
	timings(P_384, 0, ctx);
	timings(P_384, 1, ctx);
	timings(P_521, 0, ctx);
	timings(P_521, 1, ctx);
#endif


	if (ctx)
		BN_CTX_free(ctx);
	BN_free(p); BN_free(a);	BN_free(b);
	EC_GROUP_free(group);
	EC_POINT_free(P);
	EC_POINT_free(Q);
	EC_POINT_free(R);
	BN_free(x); BN_free(y); BN_free(z);

	if (P_192) EC_GROUP_free(P_192);
	if (P_224) EC_GROUP_free(P_224);
	if (P_256) EC_GROUP_free(P_256);
	if (P_384) EC_GROUP_free(P_384);
	if (P_521) EC_GROUP_free(P_521);

	ENGINE_cleanup();
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();
	ERR_remove_state(0);
	CRYPTO_mem_leaks_fp(stderr);
	
	return 0;
	}
Exemple #11
0
int main(
    int argc,
    char **argv)
{
    scmcon *testconp = NULL;
    scmcon *realconp = NULL;
    scm *scmp = NULL;
    FILE *sfile = NULL;
    char *thedelfile = NULL;
    char *topdir = NULL;
    char *thefile = NULL;
    char *outfile = NULL;
    char *outfull = NULL;
    char *outdir = NULL;
    char *tmpdsn = NULL;
    char *ne;
    char *porto = NULL;
    char errmsg[1024];
    char *skifile = NULL;
    int ians = 0;
    int do_create = 0;
    int do_delete = 0;
    int do_sockopts = 0;
    int do_fileopts = 0;
    int use_filelist = 0;
    int perpetual = 0;
    int really = 0;
    int trusted = 0;
    int force = 0;
    int allowex = 0;
    int sta = 0;
    int s;
    int c;

    (void)setbuf(stdout, NULL);
    if (argc <= 1)
    {
        usage();
        return (1);
    }
    while ((c = getopt(argc, argv, "t:xyhad:f:F:lLwz:pm:c:s")) != EOF)
    {
        switch (c)
        {
        case 'a':
            allowex = 1;
            break;
        case 't':
            do_create++;
            topdir = optarg;
            break;
        case 'x':
            do_delete++;
            break;
        case 'y':
            force++;
            break;
        case 'D':
            trusted++;
        case 'd':
            thedelfile = optarg;
            break;
        case 'F':
            trusted++;
        case 'f':
            thefile = optarg;
            break;
        case 'L':
            trusted++;
        case 'l':
            use_filelist++;
            break;
        case 'w':
            do_sockopts++;
            break;
        case 'z':
            do_fileopts++;
            porto = optarg;
            break;
        case 'p':
            perpetual++;
            break;
        case 'c':
            skifile = optarg;
            break;
        case 'h':
            usage();
            return (0);
        case 's':
            strict_profile_checks = 1;  // global from myssl.c
            strict_profile_checks_cms = 1;      // global from roa_validate.c
            break;
        default:
            (void)fprintf(stderr, "Invalid option '%c'\n", c);
            usage();
            return (1);
        }
    }
    // if there is anything left in argv, or no operation specified, warn user
    if (optind < argc)
    {
        (void)printf("Extra arguments at the end of the command line.\n");
        usage();
        return (1);
    }
    if ((do_create + do_delete + do_sockopts + do_fileopts) == 0 &&
            thefile == 0 && thedelfile == 0 && skifile == 0 && use_filelist == 0)
    {
        (void)printf("You need to specify at least one operation "
                     "(e.g. -f file).\n");
        usage();
        return (1);
    }
    OPEN_LOG("rcli", LOG_USER);
    if (!my_config_load())
    {
        LOG(LOG_ERR, "can't load configuration");
        exit(EXIT_FAILURE);
    }
    if (force == 0)
    {
        if (do_delete > 0)
        {
            ians = yorn("Do you REALLY want to delete all database tables");
            if (ians <= 0)
            {
                LOG(LOG_NOTICE, "Delete operation cancelled");
                return (1);
            }
            really++;
        }
        if ((do_create > 0) && (really == 0))
        {
            ians = yorn("Do you REALLY want to create all database tables");
            if (ians <= 0)
            {
                LOG(LOG_NOTICE, "Create operation cancelled");
                return (1);
            }
            really++;
        }
    }
    scmp = initscm();
    if (scmp == NULL)
    {
        LOG(LOG_ERR, "Internal error: cannot initialize database schema");
        return (-2);
    }
    /*
     * If a create or delete operation is being performed, then a test dsn
     * will be needed; create it now and defer the creation of the real dsn
     * until later. Otherwise, create the real dsn.
     *
     * A test dsn is needed for operations that operate on the overall
     * database state as opposed to the rpki tables, namely the create and
     * delete operations.
     */
    if ((do_create + do_delete) > 0)
    {
        /*
         * Note that in the following line, we do not intend to edit
         * the database named "information_schema".  We are simply
         * filling in the "database name" parameter with something
         * that is guaranteed to be valid for MySQL.
         */
        tmpdsn = makedsnscm(scmp->dsnpref, "information_schema",
                            CONFIG_DATABASE_USER_get(),
                            CONFIG_DATABASE_PASSWORD_get());
        if (tmpdsn == NULL)
        {
            membail();
            return (-1);
        }
        testconp = connectscm(tmpdsn, errmsg, 1024);
        memset(tmpdsn, 0, strlen(tmpdsn));
        free((void *)tmpdsn);
        if (testconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN: %s", errmsg);
            freescm(scmp);
            return (-1);
        }
    }
    else
    {
        realconp = connectscm(scmp->dsn, errmsg, 1024);
        if (realconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN %s: %s", scmp->dsn,
                errmsg);
            freescm(scmp);
            return (-1);
        }
    }
    /*
     * Process command line options in the following order: delete, create,
     * dofile, dodir, listener.
     */
    if (do_delete > 0)
        sta = deleteop(testconp, scmp);
    if ((do_create > 0) && (sta == 0))  /* first phase of create */
        sta = createop(testconp, scmp);
    /*
     * Don't need the test connection any more
     */
    if (testconp != NULL)
    {
        disconnectscm(testconp);
        testconp = NULL;
    }
    /*
     * If there has been an error or if we're done because the database was
     * just deleted and not re-created, bail out.
     */
    if (sta < 0 || (do_delete > 0 && do_create == 0))
    {
        if (realconp != NULL)
            disconnectscm(realconp);
        freescm(scmp);
        if (tdir != NULL)
            free((void *)tdir);
        return (sta);
    }
    /*
     * If a connection to the real DSN has not been opened yet, open it now.
     */
    if (realconp == NULL)
    {
        realconp = connectscm(scmp->dsn, errmsg, 1024);
        if (realconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN %s: %s",
                scmp->dsn, errmsg);
            freescm(scmp);
            if (tdir != NULL)
                free((void *)tdir);
            return (-1);
        }
    }
    /*
     * If a create operation was requested, complete it now.
     */
    if ((do_create > 0) && (sta == 0))
        sta = create2op(scmp, realconp, topdir);
    /*
     * If the top level repository directory is not set, then retrieve it from
     * the database.
     */
    if ((tdir == NULL) && (sta == 0))
    {
        tdir = retrieve_tdir(scmp, realconp, &sta);
        if (tdir == NULL)
            LOG(LOG_ERR,
                "Cannot retrieve top level repository info from DB");
    }
    if (sta == 0)
    {
        LOG(LOG_INFO, "Top level repository directory is %s", tdir);
        tdirlen = strlen(tdir);
    }
    /*
     * Setup for actual SSL operations
     */
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    LOG(LOG_NOTICE, "Rsync client session started");
    if (thefile != NULL && sta == 0)
    {
        // Check that the file is in the repository, ask if not and force is
        // off
        sta = splitdf(NULL, NULL, thefile, &outdir, &outfile, &outfull);
        if (sta == 0)
        {
            if (strncmp(tdir, outdir, tdirlen) != 0 && force == 0)
            {
                ians =
                    yorn("That file is not in the repository. Proceed anyway");
                if (ians <= 0)
                    sta = 1;
            }
            // if ( strstr(outdir, "TRUST") != NULL )
            // trusted++;
            // if the user has declared it to be trusted
            // ask for verification unless force is set
            if (trusted > 0 && force == 0 && sta == 0)
            {
                ians = yorn("Really declare this file as trusted");
                if (ians <= 0)
                    sta = 1;
            }
            if (sta == 1)
                LOG(LOG_NOTICE, "File operation cancelled");
            if (sta == 0)
            {
                LOG(LOG_INFO, "Attempting add: %s", outfile);
                setallowexpired(allowex);
                sta = add_object(scmp, realconp, outfile, outdir, outfull,
                                 trusted);
                if (sta < 0)
                {
                    LOG(LOG_ERR,
                        "Add failed: %s: error %s (%d)",
                        thefile, err2string(sta), sta);
                    if (sta == ERR_SCM_SQL)
                    {
                        ne = geterrorscm(realconp);
                        if (ne != NULL && ne != 0)
                            LOG(LOG_ERR, "\t%s", ne);
                    }
                }
                else
                    LOG(LOG_INFO, "Add succeeded: %s", outfile);
            }
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }
        else
            LOG(LOG_ERR, "%s (%d)", err2string(sta), sta);
    }
    if (use_filelist > 0 && sta == 0)
    {
        char *line = NULL;
        size_t len = 0;
        ssize_t read;
        int status;

        setallowexpired(allowex);
        while ((read = getline(&line, &len, stdin)) != -1)
        {
            if (read == 0)
                continue;

            // Trim newline and skip line if empty
            if (line[read - 1] == '\n')
                line[read - 1] = '\0';
            if (strlen(line) == 0)
                continue;

            // Split directory and file components of path
            status = splitdf(NULL, NULL, line, &outdir, &outfile, &outfull);
            if (status != 0)
            {
                LOG(LOG_ERR, "%s (%d)", err2string(status), status);
                continue;
            }

            LOG(LOG_INFO, "Attempting add: %s", outfile);

            // Warn if file not within repository directory
            if (strncmp(tdir, outdir, tdirlen) != 0)
                LOG(LOG_WARNING, "%s is not in the repository", line);

            // Add
            status = add_object(scmp, realconp, outfile, outdir, outfull,
                                trusted);
            if (status == 0)
            {
                LOG(LOG_INFO, "Add succeeded: %s", outfile);
            }
            else
            {
                LOG(LOG_ERR, "Add failed: %s: error %s (%d)",
                    line, err2string(status), status);
                if (status == ERR_SCM_SQL)
                {
                    ne = geterrorscm(realconp);
                    if (ne != NULL && ne != 0)
                        LOG(LOG_ERR, "\t%s", ne);
                }
            }
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }

        free(line);
    }
    if (thedelfile != NULL && sta == 0)
    {
        sta = splitdf(NULL, NULL, thedelfile, &outdir, &outfile, &outfull);
        if (sta == 0)
        {
            sta = delete_object(scmp, realconp, outfile, outdir, outfull, 0);
            if (sta < 0)
            {
                LOG(LOG_ERR,
                    "Could not delete file %s: error %s (%d)",
                    thedelfile, err2string(sta), sta);
                if (sta == ERR_SCM_SQL)
                {
                    ne = geterrorscm(realconp);
                    if (ne != NULL && ne != 0)
                        LOG(LOG_ERR, "\t%s", ne);
                }
            }
            else
                LOG(LOG_INFO, "Delete operation succeeded (%s removed)",
                    thedelfile);
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }
        else
            LOG(LOG_ERR, "Error: %s (%d)", err2string(sta), sta);
    }
    if ((do_sockopts + do_fileopts) > 0 && sta == 0)
    {
        int protos = (-1);
        const int max_makesock_attempts = 10;
        int makesock_failures = 0;
        do
        {
            if (do_sockopts > 0)
            {
                uint16_t port = CONFIG_RPKI_PORT_get();
                s = makesock(port, &protos);
                if (s < 0)
                {
                    makesock_failures++;
                    LOG(LOG_ERR,
                        "Failed to listen on port %" PRIu16 " (failure #%d)", port,
                        makesock_failures);
                    sleep(1);
                    if (makesock_failures >= max_makesock_attempts)
                    {
                        LOG(LOG_ERR,
                            "%d failed attempts to create socket. Aborting.",
                            max_makesock_attempts);
                        sta = -1;
                        break;
                    }
                }
                else
                {
                    makesock_failures = 0;
                    FLUSH_LOG();
                    sta = sockline(scmp, realconp, s);
                    LOG(LOG_INFO, "Socket connection closed");
                    FLUSH_LOG();
                    (void)close(s);
                }
            }
            if (do_fileopts > 0 && porto != NULL)
            {
                if (!isatty(0))
                {
                    LOG(LOG_DEBUG, "Opening stdin");
                    sfile = stdin;
                    sta = fileline(scmp, realconp, sfile);
                }
                else
                {
                    LOG(LOG_DEBUG, "Opening a socket cmdfile %s", porto);
                    sfile = fopen(porto, "r");
                    if (sfile == NULL)
                        LOG(LOG_ERR, "Could not open cmdfile");
                    else
                    {
                        sta = fileline(scmp, realconp, sfile);
                        LOG(LOG_DEBUG, "Cmdfile closed");
                        (void)fclose(sfile);
                    }
                }
            }
            if (sta == 0 && skifile)
            {
                LOG(LOG_DEBUG, "Starting skifile %s", skifile);
                sta = read_SKI_blocks(scmp, realconp, skifile);
                if (sta > 0)
                    sta = 0;
                if (sta)
                    LOG(LOG_ERR, "Error with skifile: %s (%d)",
                        err2string(sta), sta);
            }
        } while (perpetual > 0);
        if (protos >= 0)
            (void)close(protos);
    }
    if (sta == 0 && skifile)
    {
        LOG(LOG_DEBUG, "Starting skifile %s", skifile);
        sta = read_SKI_blocks(scmp, realconp, skifile);
        if (sta > 0)
            sta = 0;
        if (sta)
            LOG(LOG_ERR, "Error with skifile: %s (%d)", err2string(sta),
                sta);
    }
    (void)ranlast(scmp, realconp, "RSYNC");
    sqcleanup();
    if (realconp != NULL)
        disconnectscm(realconp);
    freescm(scmp);
    if (tdir != NULL)
        free((void *)tdir);
    LOG(LOG_NOTICE, "Rsync client session ended");
    config_unload();
    CLOSE_LOG();
    return (sta);
}
Exemple #12
0
int MAIN(int argc, char **argv)
{
    BN_GENCB cb;
# ifndef OPENSSL_NO_ENGINE
    ENGINE *e = NULL;
# endif
    int ret = 1;
    int i, num = DEFBITS;
    long l;
    const EVP_CIPHER *enc = NULL;
    unsigned long f4 = RSA_F4;
    char *outfile = NULL;
    char *passargout = NULL, *passout = NULL;
# ifndef OPENSSL_NO_ENGINE
    char *engine = NULL;
# endif
    char *inrand = NULL;
    BIO *out = NULL;
    BIGNUM *bn = BN_new();
    RSA *rsa = NULL;

    if (!bn)
        goto err;

    apps_startup();
    BN_GENCB_set(&cb, genrsa_cb, bio_err);

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto err;
    if ((out = BIO_new(BIO_s_file())) == NULL) {
        BIO_printf(bio_err, "unable to create BIO for output\n");
        goto err;
    }

    argv++;
    argc--;
    for (;;) {
        if (argc <= 0)
            break;
        if (strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            outfile = *(++argv);
        } else if (strcmp(*argv, "-3") == 0)
            f4 = 3;
        else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0)
            f4 = RSA_F4;
# ifndef OPENSSL_NO_ENGINE
        else if (strcmp(*argv, "-engine") == 0) {
            if (--argc < 1)
                goto bad;
            engine = *(++argv);
        }
# endif
        else if (strcmp(*argv, "-rand") == 0) {
            if (--argc < 1)
                goto bad;
            inrand = *(++argv);
        }
# ifndef OPENSSL_NO_DES
        else if (strcmp(*argv, "-des") == 0)
            enc = EVP_des_cbc();
        else if (strcmp(*argv, "-des3") == 0)
            enc = EVP_des_ede3_cbc();
# endif
# ifndef OPENSSL_NO_IDEA
        else if (strcmp(*argv, "-idea") == 0)
            enc = EVP_idea_cbc();
# endif
# ifndef OPENSSL_NO_SEED
        else if (strcmp(*argv, "-seed") == 0)
            enc = EVP_seed_cbc();
# endif
# ifndef OPENSSL_NO_AES
        else if (strcmp(*argv, "-aes128") == 0)
            enc = EVP_aes_128_cbc();
        else if (strcmp(*argv, "-aes192") == 0)
            enc = EVP_aes_192_cbc();
        else if (strcmp(*argv, "-aes256") == 0)
            enc = EVP_aes_256_cbc();
# endif
# ifndef OPENSSL_NO_CAMELLIA
        else if (strcmp(*argv, "-camellia128") == 0)
            enc = EVP_camellia_128_cbc();
        else if (strcmp(*argv, "-camellia192") == 0)
            enc = EVP_camellia_192_cbc();
        else if (strcmp(*argv, "-camellia256") == 0)
            enc = EVP_camellia_256_cbc();
# endif
        else if (strcmp(*argv, "-passout") == 0) {
            if (--argc < 1)
                goto bad;
            passargout = *(++argv);
        } else
            break;
        argv++;
        argc--;
    }
    if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) {
 bad:
        BIO_printf(bio_err, "usage: genrsa [args] [numbits]\n");
        BIO_printf(bio_err,
                   " -des            encrypt the generated key with DES in cbc mode\n");
        BIO_printf(bio_err,
                   " -des3           encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
# ifndef OPENSSL_NO_IDEA
        BIO_printf(bio_err,
                   " -idea           encrypt the generated key with IDEA in cbc mode\n");
# endif
# ifndef OPENSSL_NO_SEED
        BIO_printf(bio_err, " -seed\n");
        BIO_printf(bio_err,
                   "                 encrypt PEM output with cbc seed\n");
# endif
# ifndef OPENSSL_NO_AES
        BIO_printf(bio_err, " -aes128, -aes192, -aes256\n");
        BIO_printf(bio_err,
                   "                 encrypt PEM output with cbc aes\n");
# endif
# ifndef OPENSSL_NO_CAMELLIA
        BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n");
        BIO_printf(bio_err,
                   "                 encrypt PEM output with cbc camellia\n");
# endif
        BIO_printf(bio_err, " -out file       output the key to 'file\n");
        BIO_printf(bio_err,
                   " -passout arg    output file pass phrase source\n");
        BIO_printf(bio_err,
                   " -f4             use F4 (0x10001) for the E value\n");
        BIO_printf(bio_err, " -3              use 3 for the E value\n");
# ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err,
                   " -engine e       use engine e, possibly a hardware device.\n");
# endif
        BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
                   LIST_SEPARATOR_CHAR);
        BIO_printf(bio_err,
                   "                 load the file (or the files in the directory) into\n");
        BIO_printf(bio_err, "                 the random number generator\n");
        goto err;
    }

    ERR_load_crypto_strings();

    if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto err;
    }
# ifndef OPENSSL_NO_ENGINE
    e = setup_engine(bio_err, engine, 0);
# endif

    if (outfile == NULL) {
        BIO_set_fp(out, stdout, BIO_NOCLOSE);
# ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
# endif
    } else {
        if (BIO_write_filename(out, outfile) <= 0) {
            perror(outfile);
            goto err;
        }
    }

    if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
        && !RAND_status()) {
        BIO_printf(bio_err,
                   "warning, not much extra random data, consider using the -rand option\n");
    }
    if (inrand != NULL)
        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                   app_RAND_load_files(inrand));

    BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
               num);
# ifdef OPENSSL_NO_ENGINE
    rsa = RSA_new();
# else
    rsa = RSA_new_method(e);
# endif
    if (!rsa)
        goto err;

    if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
        goto err;

    app_RAND_write_file(NULL, bio_err);

    /*
     * We need to do the following for when the base number size is < long,
     * esp windows 3.1 :-(.
     */
    l = 0L;
    for (i = 0; i < rsa->e->top; i++) {
# ifndef SIXTY_FOUR_BIT
        l <<= BN_BITS4;
        l <<= BN_BITS4;
# endif
        l += rsa->e->d[i];
    }
    BIO_printf(bio_err, "e is %ld (0x%lX)\n", l, l);
    {
        PW_CB_DATA cb_data;
        cb_data.password = passout;
        cb_data.prompt_info = outfile;
        if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
                                         (pem_password_cb *)password_callback,
                                         &cb_data))
            goto err;
    }

    ret = 0;
 err:
    if (bn)
        BN_free(bn);
    if (rsa)
        RSA_free(rsa);
    if (out)
        BIO_free_all(out);
    if (passout)
        OPENSSL_free(passout);
    if (ret != 0)
        ERR_print_errors(bio_err);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
int main(int argc, char *argv[]) {
    X509 *cert;
    X509 *cacert;
    X509_CRL *crl;
    X509_STORE *store;
    X509_LOOKUP *lookup;
    X509_STORE_CTX *verify_ctx;
    STACK_OF(X509) *untrusted;
    STACK_OF(X509_CRL) *crls;
    FILE *fp;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* read the client certificate */
    if (!(fp = fopen(CLIENT_CERT, "r"))) {
        int_error("Error reading client certificate file");
    }
    if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL))) {
        int_error("Error reading client certificate in file");
    }
    fclose(fp);

    /* read CA certificate */
    if (!(fp = fopen(CA_FILE, "r"))) {
        int_error("Error reading CA certificate file");
    }
    if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
        int_error("Error reading CA certificate in file");
    }
    fclose(fp);

    // Read CRL
    if (!(fp = fopen(CRL_FILE, "r"))) {
        int_error("Error opening CRL file");
    }
    if (!(crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL))) {
        int_error("Error reading CRL");
    }
    fclose(fp);
    
    /* create the cert store and set the verify callback */
    if (!(store = X509_STORE_new())) {
        int_error("Error creating X509_STORE_CTX object");
    }
    // Add CA cert to Store
    if (X509_STORE_add_cert(store, cacert) != 1) {
        int_error("Error adding CA certificate to certificate store");
    }
    // Add CRL to Store
    if (X509_STORE_add_crl(store, crl) != 1) {
        int_error("Error adding CRL to certificate store");
    }
    X509_STORE_set_verify_cb_func(store, verify_callback);
    /* set the flags of the store so that the CRLs are consulted */
    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
    
    // Create an empty X509_Stack for untrusted
    if (!(untrusted = sk_X509_new_null())) {
        int_error("Error creating X509_Stack");
    }
    // Create a CRL_Stack 
    if (!(crls = sk_X509_CRL_new_null())) {
        int_error("Error creating X509_CRL");
    }
    // Add CRL to CRL_Stack
    if (sk_X509_CRL_push(crls, crl) != 1) {
        int_error("Error adding a CRL to the Stack of CRLs");
    }

    /* create a verification context and initialize it */
    if (!(verify_ctx = X509_STORE_CTX_new())) {
        int_error("Error creating X509_STORE_CTX object");
    }
    // We are explicitly adding an empty X509_Stack for untrusted
    if (X509_STORE_CTX_init(verify_ctx, store, cert, untrusted) != 1) {
        int_error("Error initializing verification context");
    }
    X509_STORE_CTX_set0_crls(verify_ctx, crls);
    /* verify the certificate */
    if (X509_verify_cert(verify_ctx) != 1) {
        int_error("Error verifying the certificate");
    }
    else {
        printf("Certificate verified correctly!\n");
    }
    return 0;
}
int cve_1790app(char *filename)
{
	int encrypt,flags_nm=0,out_size=0;
	PKCS7 *pkcs7;
	const EVP_CIPHER *cipher;
	X509 *cert;
	EVP_PKEY *pkey;
	FILE *fp;
	BIO *pkcs7_bio,*out,*in_fileBIO;
	int i=0;
	
	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();
		

	if (!(out = BIO_new_fp(stdout, BIO_NOCLOSE)))
	{
		fprintf(stderr, "Error creating output BIO objects\n");
		goto err;
	}
	
	// read from file and Decrypt 
	{
		if (!(fp = fopen(RSA_SERVER_KEY, "r")) ||!(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)))
		{
			printf("Error reading private key in %s\n",RSA_SERVER_KEY);
			goto err;
		}
		fclose(fp);
		
		if (!(fp = fopen(RSA_SERVER_CERT, "r")) ||!(cert = PEM_read_X509(fp, NULL, NULL, NULL)))
		{
			printf( "Error reading decryption certificate in %s\n",	RSA_SERVER_CERT);
			goto err;
		}
		fclose(fp);
		
		//create a file BIO for input file
		in_fileBIO = BIO_new_file(filename,"r");
		if( in_fileBIO == NULL){ 
			printf("Error in creating bio file\n"); 
			goto err;
		}		
		
		if (!(pkcs7 = SMIME_read_PKCS7(in_fileBIO, &pkcs7_bio)))
		{
			printf("\nError reading PKCS#7 object\n");
			goto err;
		}
		
		printf("Invoking PKCS7_decrypt function..\n");
		if (PKCS7_decrypt(pkcs7, pkey, cert, out, flags_nm) != 1)
		{
			printf("Error decrypting PKCS#7 object\n");
			goto err;
		}
	}

	BIO_free(in_fileBIO);

	return 0;
err:
	return -1;
}
Exemple #15
0
int
main(int argc, char **argv)
{
	BIO *bio_in, *bio_content, *bio_out, *bio_cert, *bio_pkey;
	STACK_OF(X509) *certs;
	const EVP_CIPHER *cipher;
	EVP_PKEY *pkey;
	X509_STORE *store;
	X509 *cert;
	PKCS7 *p7;
	size_t len;
	char *out;
	int flags;

	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	/*
	 * A bunch of setup...
	 */
	cipher = EVP_aes_256_cbc();
	if (cipher == NULL)
		fatal("cipher");

	certs = sk_X509_new_null();
	if (certs == NULL)
		fatal("sk_X509_new_null");

	bio_cert = BIO_new_mem_buf((char *)certificate, sizeof(certificate));
	if (bio_cert == NULL)
		fatal("BIO_new_mem_buf certificate");

	cert = PEM_read_bio_X509_AUX(bio_cert, NULL, NULL, NULL);
	if (cert == NULL)
		fatal("PEM_read_bio_X509_AUX");
	sk_X509_push(certs, cert);

	store = X509_STORE_new();
	if (store == NULL)
		fatal("X509_STORE_new");
	X509_STORE_set_verify_cb(store, x509_store_callback);

	bio_pkey = BIO_new_mem_buf((char *)private_key, sizeof(private_key));
	if (bio_pkey == NULL)
		fatal("BIO_new_mem_buf private_key");

	pkey = PEM_read_bio_PrivateKey(bio_pkey, NULL, NULL, NULL);
	if (pkey == NULL)
		fatal("PEM_read_bio_PrivateKey");

	bio_content = BIO_new_mem_buf((char *)message, sizeof(message));
	if (bio_content == NULL)
		fatal("BIO_new_mem_buf message");

	/*
	 * Encrypt and then decrypt.
	 */
	if (BIO_reset(bio_content) != 1)
		fatal("BIO_reset");
	bio_out = BIO_new(BIO_s_mem());
	if (bio_out == NULL)
		fatal("BIO_new");

	p7 = PKCS7_encrypt(certs, bio_content, cipher, 0);
	if (p7 == NULL)
		fatal("PKCS7_encrypt");
	if (PEM_write_bio_PKCS7(bio_out, p7) != 1)
		fatal("PEM_write_bio_PKCS7");
	PKCS7_free(p7);

	bio_in = bio_out;
	bio_out = BIO_new(BIO_s_mem());
	if (bio_out == NULL)
		fatal("BIO_new");

	p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL);
	if (p7 == NULL)
		fatal("PEM_read_bio_PKCS7");
	if (PKCS7_decrypt(p7, pkey, cert, bio_out, 0) != 1)
		fatal("PKCS7_decrypt");

	len = BIO_get_mem_data(bio_out, &out);
	message_compare(out, len);

	BIO_free(bio_out);

	/*
	 * Sign and then verify.
	 */
	if (BIO_reset(bio_content) != 1)
		fatal("BIO_reset");
	bio_out = BIO_new(BIO_s_mem());
	if (bio_out == NULL)
		fatal("BIO_new");

	p7 = PKCS7_sign(cert, pkey, certs, bio_content, 0);
	if (p7 == NULL)
		fatal("PKCS7_sign");
	if (PEM_write_bio_PKCS7(bio_out, p7) != 1)
		fatal("PEM_write_bio_PKCS7");
	PKCS7_free(p7);

	bio_in = bio_out;
	bio_out = BIO_new(BIO_s_mem());
	if (bio_out == NULL)
		fatal("BIO_new");

	p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL);
	if (p7 == NULL)
		fatal("PEM_read_bio_PKCS7");
	if (PKCS7_verify(p7, certs, store, NULL, bio_out, 0) != 1)
		fatal("PKCS7_verify");

	len = BIO_get_mem_data(bio_out, &out);
	message_compare(out, len);

	BIO_free(bio_in);
	BIO_free(bio_out);

	/*
	 * Sign and then verify with a detached signature.
	 */
	if (BIO_reset(bio_content) != 1)
		fatal("BIO_reset");
	bio_out = BIO_new(BIO_s_mem());
	if (bio_out == NULL)
		fatal("BIO_new");

	flags = PKCS7_DETACHED|PKCS7_PARTIAL;
	p7 = PKCS7_sign(NULL, NULL, NULL, bio_content, flags);
	if (p7 == NULL)
		fatal("PKCS7_sign");
	if (PKCS7_sign_add_signer(p7, cert, pkey, NULL, flags) == NULL)
		fatal("PKCS7_sign_add_signer");
	if (PKCS7_final(p7, bio_content, flags) != 1)
		fatal("PKCS7_final");
	if (PEM_write_bio_PKCS7(bio_out, p7) != 1)
		fatal("PEM_write_bio_PKCS7");
	PKCS7_free(p7);

	/* bio_out contains only the detached signature. */
	bio_in = bio_out;
	if (BIO_reset(bio_content) != 1)
		fatal("BIO_reset");

	bio_out = BIO_new(BIO_s_mem());
	if (bio_out == NULL)
		fatal("BIO_new");

	p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL);
	if (p7 == NULL)
		fatal("PEM_read_bio_PKCS7");
	if (PKCS7_verify(p7, certs, store, bio_content, bio_out, flags) != 1)
		fatal("PKCS7_verify");

	len = BIO_get_mem_data(bio_out, &out);
	message_compare(out, len);

	BIO_free(bio_in);
	BIO_free(bio_out);
	BIO_free(bio_content);

	return 0;
}
Exemple #16
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	char **args, *outfile = NULL;
	char *passarg = NULL;
	BIO *in = NULL, *out = NULL;
	const EVP_CIPHER *cipher = NULL;
	int outformat;
	int text = 0;
	EVP_PKEY *pkey=NULL;
	EVP_PKEY_CTX *ctx = NULL;
	char *pass = NULL;
	int badarg = 0;
	int ret = 1, rv;

	int do_param = 0;

	if (bio_err == NULL)
		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;

	outformat=FORMAT_PEM;

	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();
	args = argv + 1;
	while (!badarg && *args && *args[0] == '-')
		{
		if (!strcmp(*args,"-outform"))
			{
			if (args[1])
				{
				args++;
				outformat=str2fmt(*args);
				}
			else badarg = 1;
			}
		else if (!strcmp(*args,"-pass"))
			{
			if (!args[1]) goto bad;
			passarg= *(++args);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*args,"-engine") == 0)
			{
			if (!args[1])
				goto bad;
        		e = setup_engine(bio_err, *(++args), 0);
			}
#endif
		else if (!strcmp (*args, "-paramfile"))
			{
			if (!args[1])
				goto bad;
			args++;
			if (do_param == 1)
				goto bad;
			if (!init_keygen_file(bio_err, &ctx, *args, e))
				goto end;
			}
		else if (!strcmp (*args, "-out"))
			{
			if (args[1])
				{
				args++;
				outfile = *args;
				}
			else badarg = 1;
			}
		else if (strcmp(*args,"-algorithm") == 0)
			{
			if (!args[1])
				goto bad;
			if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
				goto end;
			}
		else if (strcmp(*args,"-pkeyopt") == 0)
			{
			if (!args[1])
				goto bad;
			if (!ctx)
				{
				BIO_puts(bio_err, "No keytype specified\n");
				goto bad;
				}
			else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
				{
				BIO_puts(bio_err, "parameter setting error\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			}
		else if (strcmp(*args,"-genparam") == 0)
			{
			if (ctx)
				goto bad;
			do_param = 1;
			}
		else if (strcmp(*args,"-text") == 0)
			text=1;
		else
			{
			cipher = EVP_get_cipherbyname(*args + 1);
			if (!cipher)
				{
				BIO_printf(bio_err, "Unknown cipher %s\n",
								*args + 1);
				badarg = 1;
				}
			if (do_param == 1)
				badarg = 1;
			}
		args++;
		}

	if (!ctx)
		badarg = 1;

	if (badarg)
		{
		bad:
		BIO_printf(bio_err, "Usage: genpkey [options]\n");
		BIO_printf(bio_err, "where options may be\n");
		BIO_printf(bio_err, "-out file          output file\n");
		BIO_printf(bio_err, "-outform X         output format (DER or PEM)\n");
		BIO_printf(bio_err, "-pass arg          output file pass phrase source\n");
		BIO_printf(bio_err, "-<cipher>          use cipher <cipher> to encrypt the key\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, "-engine e          use engine e, possibly a hardware device.\n");
#endif
		BIO_printf(bio_err, "-paramfile file    parameters file\n");
		BIO_printf(bio_err, "-algorithm alg     the public key algorithm\n");
		BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
				            "                   to value <value>\n");
		BIO_printf(bio_err, "-genparam          generate parameters, not key\n");
		BIO_printf(bio_err, "-text              print the in text\n");
		BIO_printf(bio_err, "NB: options order may be important!  See the manual page.\n");
		goto end;
		}

	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
		{
		BIO_puts(bio_err, "Error getting password\n");
		goto end;
		}

	if (outfile)
		{
		if (!(out = BIO_new_file (outfile, "wb")))
			{
			BIO_printf(bio_err,
				 "Can't open output file %s\n", outfile);
			goto end;
			}
		}
	else
		{
		out = BIO_new_fp (stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			out = BIO_push(tmpbio, out);
			}
#endif
		}

	EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
	EVP_PKEY_CTX_set_app_data(ctx, bio_err);

	if (do_param)
		{
		if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
			{
			BIO_puts(bio_err, "Error generating parameters\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	else
		{
		if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
			{
			BIO_puts(bio_err, "Error generating key\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	if (do_param)
		rv = PEM_write_bio_Parameters(out, pkey);
	else if (outformat == FORMAT_PEM) 
		rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
								NULL, pass);
	else if (outformat == FORMAT_ASN1)
		rv = i2d_PrivateKey_bio(out, pkey);
	else
		{
		BIO_printf(bio_err, "Bad format specified for key\n");
		goto end;
		}

	if (rv <= 0)
		{
		BIO_puts(bio_err, "Error writing key\n");
		ERR_print_errors(bio_err);
		}

	if (text)
		{
		if (do_param)
			rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
		else
			rv = EVP_PKEY_print_private(out, pkey, 0, NULL);

		if (rv <= 0)
			{
			BIO_puts(bio_err, "Error printing key\n");
			ERR_print_errors(bio_err);
			}
		}

	ret = 0;

	end:
	if (pkey)
		EVP_PKEY_free(pkey);
	if (ctx)
		EVP_PKEY_CTX_free(ctx);
	if (out)
		BIO_free_all(out);
	BIO_free(in);
	if (pass)
		OPENSSL_free(pass);

	return ret;
	}
int
certproc(int netsock, int filesock)
{
	char		*csr, *chain, *url;
	unsigned char	*csrcp, *chaincp;
	size_t		 csrsz, chainsz;
	int		 i, rc, idx, cc;
	enum certop	 op;
	long		 lval;
	X509		*x, *chainx;
	X509_EXTENSION	*ext;
	X509V3_EXT_METHOD *method;
	void		*entries;
	STACK_OF(CONF_VALUE) *val;
	CONF_VALUE	*nval;

	ext = NULL;
	idx = -1;
	method = NULL;
	chain = csr = url = NULL;
	rc = 0;
	x = chainx = NULL;

	/* File-system and sandbox jailing. */

	if ( ! sandbox_before())
		goto out;

	ERR_load_crypto_strings();

	if ( ! dropfs(PATH_VAR_EMPTY))
		goto out;
	else if ( ! dropprivs())
		goto out;
	else if ( ! sandbox_after())
		goto out;

	/* Read what the netproc wants us to do. */

	op = CERT__MAX;
	if (0 == (lval = readop(netsock, COMM_CSR_OP)))
		op = CERT_STOP;
	else if (CERT_REVOKE == lval || CERT_UPDATE == lval)
		op = lval;

	if (CERT_STOP == op) {
		rc = 1;
		goto out;
	} else if (CERT__MAX == op) {
		warnx("unknown operation from netproc");
		goto out;
	}

	/* 
	 * Pass revocation right through to fileproc. 
	 * If the reader is terminated, ignore it.
	 */

	if (CERT_REVOKE == op) {
		if (writeop(filesock, COMM_CHAIN_OP, FILE_REMOVE) >= 0)
			rc = 1;
		goto out;
	}

	/*
	 * Wait until we receive the DER encoded (signed) certificate
	 * from the network process.
	 * Then convert the DER encoding into an X509 certificate.
	 */

	if (NULL == (csr = readbuf(netsock, COMM_CSR, &csrsz)))
		goto out;

	csrcp = (u_char *)csr;
	x = d2i_X509(NULL, (const u_char **)&csrcp, csrsz);
	if (NULL == x) {
		warnx("d2i_X509");
		goto out;
	}

	/*
	 * Extract the CA Issuers from its NID.
	 * TODO: I have no idea what I'm doing.
	 */

	idx = X509_get_ext_by_NID(x, NID_info_access, idx);
	if (idx >= 0 && NULL != (ext = X509_get_ext(x, idx)))
		method = (X509V3_EXT_METHOD *)X509V3_EXT_get(ext);

	entries = X509_get_ext_d2i(x, NID_info_access, 0, 0);
	if (NULL != method && NULL != entries) {
		val = method->i2v(method, entries, 0);
		for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
			nval = sk_CONF_VALUE_value(val, i);
			if (strcmp(nval->name, "CA Issuers - URI"))
				continue;
			url = strdup(nval->value);
			if (NULL == url) {
				warn("strdup");
				goto out;
			}
			break;
		}
	}

	if (NULL == url) {
		warnx("no CA issuer registered with certificate");
		goto out;
	}

	/* Write the CA issuer to the netsock. */

	if (writestr(netsock, COMM_ISSUER, url) <= 0)
		goto out;

	/* Read the full-chain back from the netsock. */

	if (NULL == (chain = readbuf(netsock, COMM_CHAIN, &chainsz)))
		goto out;

	/*
	 * Then check if the chain is PEM-encoded by looking to see if
	 * it begins with the PEM marker.
	 * If so, ship it as-is; otherwise, convert to a PEM encoded
	 * buffer and ship that.
	 * FIXME: if PEM, re-parse it.
	 */

	if (chainsz <= strlen(MARKER) ||
	    strncmp(chain, MARKER, strlen(MARKER))) {
		chaincp = (u_char *)chain;
		chainx = d2i_X509(NULL, 
			(const u_char **)&chaincp, chainsz);
		if (NULL == chainx) {
			warnx("d2i_X509");
			goto out;
		}
		free(chain);
		if (NULL == (chain = x509buf(chainx, &chainsz)))
			goto out;
	} 

	/* Allow reader termination to just push us out. */

	if (0 == (cc = writeop(filesock, COMM_CHAIN_OP, FILE_CREATE)))
		rc = 1;
	if (cc <= 0)
		goto out;
	if (0 == (cc = writebuf(filesock, COMM_CHAIN, chain, chainsz)))
		rc = 1;
	if (cc <= 0)
		goto out;

	/* 
	 * Next, convert the X509 to a buffer and send that. 
	 * Reader failure doesn't change anything.
	 */

	free(chain);
	if (NULL == (chain = x509buf(x, &chainsz)))
		goto out;
	if (writebuf(filesock, COMM_CSR, chain, chainsz) < 0)
		goto out;

	rc = 1;
out:
	close(netsock);
	close(filesock);
	if (NULL != x)
		X509_free(x);
	if (NULL != chainx)
		X509_free(chainx);
	free(csr);
	free(url);
	free(chain);
	ERR_print_errors_fp(stderr);
	ERR_free_strings();
	return(rc);
}
Exemple #18
0
int
sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *cert_object,
		struct sc_pkcs15_object **out_key_object)
{
	struct sc_context *ctx = p15card->card->ctx;
#ifdef ENABLE_OPENSSL
	struct sc_pkcs15_object *key_object = NULL;
	struct sc_pkcs15_prkey_info *key_info = NULL;
	X509 *x = NULL;
	BIO *mem = NULL;
	unsigned char *buff = NULL, *ptr = NULL;
	int rv;

	LOG_FUNC_CALLED(ctx);
	if (out_key_object)
		*out_key_object = NULL;

	rv = sc_pkcs15_find_prkey_by_id(p15card, &((struct sc_pkcs15_cert_info *)cert_object->data)->id, &key_object);
	if (rv == SC_ERROR_OBJECT_NOT_FOUND)
		LOG_FUNC_RETURN(ctx, SC_SUCCESS);
	LOG_TEST_RET(ctx, rv, "Find private key error");

	key_info = (struct sc_pkcs15_prkey_info *) key_object->data;

	ERR_load_ERR_strings();
	ERR_load_crypto_strings();

	sc_log(ctx, "CertValue(%i) %p", cert_object->content.len, cert_object->content.value);
	mem = BIO_new_mem_buf(cert_object->content.value, cert_object->content.len);
	if (!mem)
		LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "MEM buffer allocation error");

	x = d2i_X509_bio(mem, NULL);
	if (!x)
		LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "x509 parse error");

	buff = OPENSSL_malloc(i2d_X509(x,NULL) + EVP_MAX_MD_SIZE);
	if (!buff)
		LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "OpenSSL allocation error");

	ptr = buff;
	rv = i2d_X509_NAME(X509_get_subject_name(x), &ptr);
	if (rv <= 0)
		LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Get subject name error");

	key_info->subject.value = malloc(rv);
	if (!key_info->subject.value)
		LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Subject allocation error");

	memcpy(key_info->subject.value, buff, rv);
	key_info->subject.len = rv;

	strlcpy(key_object->label, cert_object->label, sizeof(key_object->label));

	rv = 0;

	if (x)
		X509_free(x);
	if (mem)
		BIO_free(mem);
	if (buff)
		OPENSSL_free(buff);

	ERR_clear_error();
	ERR_free_strings();

	if (out_key_object)
		*out_key_object = key_object;

	sc_log(ctx, "Subject %s", sc_dump_hex(key_info->subject.value, key_info->subject.len));
	LOG_FUNC_RETURN(ctx, rv);
#else
	LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
#endif
}
int MAIN(int argc, char **argv)
	{
	int i,badops=0,offset=0,ret=1,j;
	unsigned int length=0;
	long num,tmplen;
	BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
	int informat,indent=0, noout = 0, dump = 0;
	char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
	char *genstr=NULL, *genconf=NULL;
	unsigned char *tmpbuf;
	const unsigned char *ctmpbuf;
	BUF_MEM *buf=NULL;
	STACK_OF(OPENSSL_STRING) *osk=NULL;
	ASN1_TYPE *at=NULL;

	informat=FORMAT_PEM;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,OPENSSL_TYPE__FILE_STDERR,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	prog=argv[0];
	argc--;
	argv++;
	if ((osk=sk_OPENSSL_STRING_new_null()) == NULL)
		{
		BIO_printf(bio_err,"Memory allocation failure\n");
		goto end;
		}
	while (argc >= 1)
		{
		if 	(TINYCLR_SSL_STRCMP(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			derfile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-i") == 0)
			{
			indent=1;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-noout") == 0) noout = 1;
		else if (TINYCLR_SSL_STRCMP(*argv,"-oid") == 0)
			{
			if (--argc < 1) goto bad;
			oidfile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-offset") == 0)
			{
			if (--argc < 1) goto bad;
			offset= atoi(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-length") == 0)
			{
			if (--argc < 1) goto bad;
			length= atoi(*(++argv));
			if (length == 0) goto bad;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-dump") == 0)
			{
			dump= -1;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-dlimit") == 0)
			{
			if (--argc < 1) goto bad;
			dump= atoi(*(++argv));
			if (dump <= 0) goto bad;
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-strparse") == 0)
			{
			if (--argc < 1) goto bad;
			sk_OPENSSL_STRING_push(osk,*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-genstr") == 0)
			{
			if (--argc < 1) goto bad;
			genstr= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-genconf") == 0)
			{
			if (--argc < 1) goto bad;
			genconf= *(++argv);
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] <infile\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg   input format - one of DER PEM\n");
		BIO_printf(bio_err," -in arg       input file\n");
		BIO_printf(bio_err," -out arg      output file (output format is always DER\n");
		BIO_printf(bio_err," -noout arg    don't produce any output\n");
		BIO_printf(bio_err," -offset arg   offset into file\n");
		BIO_printf(bio_err," -length arg   length of section in file\n");
		BIO_printf(bio_err," -i            indent entries\n");
		BIO_printf(bio_err," -dump         dump unknown data in hex form\n");
		BIO_printf(bio_err," -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
		BIO_printf(bio_err," -oid file     file of extra oid definitions\n");
		BIO_printf(bio_err," -strparse offset\n");
		BIO_printf(bio_err,"               a series of these can be used to 'dig' into multiple\n");
		BIO_printf(bio_err,"               ASN1 blob wrappings\n");
		BIO_printf(bio_err," -genstr str   string to generate ASN1 structure from\n");
		BIO_printf(bio_err," -genconf file file to generate ASN1 structure from\n");
		goto end;
		}

	ERR_load_crypto_strings();

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	BIO_set_fp(out,OPENSSL_TYPE__FILE_STDOUT,BIO_NOCLOSE|BIO_FP_TEXT);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	out = BIO_push(tmpbio, out);
	}
#endif

	if (oidfile != NULL)
		{
		if (BIO_read_filename(in,oidfile) <= 0)
			{
			BIO_printf(bio_err,"problems opening %s\n",oidfile);
			ERR_print_errors(bio_err);
			goto end;
			}
		OBJ_create_objects(in);
		}

	if (infile == NULL)
		BIO_set_fp(in,OPENSSL_TYPE__FILE_STDIN,BIO_NOCLOSE);
	else
		{
		if (BIO_read_filename(in,infile) <= 0)
			{
			TINYCLR_SSL_PERROR(infile);
			goto end;
			}
		}

	if (derfile) {
		if(!(derout = BIO_new_file(derfile, "wb"))) {
			BIO_printf(bio_err,"problems opening %s\n",derfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if ((buf=BUF_MEM_new()) == NULL) goto end;
	if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */

	if (genstr || genconf)
		{
		num = do_generate(bio_err, genstr, genconf, buf);
		if (num < 0)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	else
		{

		if (informat == FORMAT_PEM)
			{
			BIO *tmp;

			if ((b64=BIO_new(BIO_f_base64())) == NULL)
				goto end;
			BIO_push(b64,in);
			tmp=in;
			in=b64;
			b64=tmp;
			}

		num=0;
		for (;;)
			{
			if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
			i=BIO_read(in,&(buf->data[num]),BUFSIZ);
			if (i <= 0) break;
			num+=i;
			}
		}
	str=buf->data;

	/* If any structs to parse go through in sequence */

	if (sk_OPENSSL_STRING_num(osk))
		{
		tmpbuf=(unsigned char *)str;
		tmplen=num;
		for (i=0; i<sk_OPENSSL_STRING_num(osk); i++)
			{
			ASN1_TYPE *atmp;
			int typ;
			j=atoi(sk_OPENSSL_STRING_value(osk,i));
			if (j == 0)
				{
				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_OPENSSL_STRING_value(osk,i));
				continue;
				}
			tmpbuf+=j;
			tmplen-=j;
			atmp = at;
			ctmpbuf = tmpbuf;
			at = d2i_ASN1_TYPE(NULL,&ctmpbuf,tmplen);
			ASN1_TYPE_free(atmp);
			if(!at)
				{
				BIO_printf(bio_err,"Error parsing structure\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			typ = ASN1_TYPE_get(at);
			if ((typ == V_ASN1_OBJECT)
				|| (typ == V_ASN1_NULL))
				{
				BIO_printf(bio_err, "Can't parse %s type\n",
					typ == V_ASN1_NULL ? "NULL" : "OBJECT");
				ERR_print_errors(bio_err);
				goto end;
				}
			/* hmm... this is a little evil but it works */
			tmpbuf=at->value.asn1_string->data;
			tmplen=at->value.asn1_string->length;
			}
		str=(char *)tmpbuf;
		num=tmplen;
		}

	if (offset >= num)
		{
		BIO_printf(bio_err, "Error: offset too large\n");
		goto end;
		}

	num -= offset;

	if ((length == 0) || ((long)length > num)) length=(unsigned int)num;
	if(derout) {
		if(BIO_write(derout, str + offset, length) != (int)length) {
			BIO_printf(bio_err, "Error writing output\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (!noout &&
	    !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
		    indent,dump))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	BIO_free(derout);
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (b64 != NULL) BIO_free(b64);
	if (ret != 0)
		ERR_print_errors(bio_err);
	if (buf != NULL) BUF_MEM_free(buf);
	if (at != NULL) ASN1_TYPE_free(at);
	if (osk != NULL) sk_OPENSSL_STRING_free(osk);
	OBJ_cleanup();
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
int MAIN(int argc, char **argv)
{
#ifndef OPENSSL_NO_ENGINE
	ENGINE 	*e = NULL;
#endif
	int 	ret = 1;
	EC_KEY 	*eckey = NULL;
	const EC_GROUP *group;
	int 	i, badops = 0;
	const EVP_CIPHER *enc = NULL;
	BIO 	*in = NULL, *out = NULL;
	int 	informat, outformat, text=0, noout=0;
	int  	pubin = 0, pubout = 0, param_out = 0;
	char 	*infile, *outfile, *prog, *engine;
	char 	*passargin = NULL, *passargout = NULL;
	char 	*passin = NULL, *passout = NULL;
	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
	int	new_form = 0;
	int	asn1_flag = OPENSSL_EC_NAMED_CURVE;
	int 	new_asn1_flag = 0;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err, OPENSSL_TYPE__FILE_STDERR, BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	engine = NULL;
	infile = NULL;
	outfile = NULL;
	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1)
		{
		if (TINYCLR_SSL_STRCMP(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-passin") == 0)
			{
			if (--argc < 1) goto bad;
			passargin= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-passout") == 0)
			{
			if (--argc < 1) goto bad;
			passargout= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv, "-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv, "-noout") == 0)
			noout = 1;
		else if (TINYCLR_SSL_STRCMP(*argv, "-text") == 0)
			text = 1;
		else if (TINYCLR_SSL_STRCMP(*argv, "-conv_form") == 0)
			{
			if (--argc < 1)
				goto bad;
			++argv;
			new_form = 1;
			if (TINYCLR_SSL_STRCMP(*argv, "compressed") == 0)
				form = POINT_CONVERSION_COMPRESSED;
			else if (TINYCLR_SSL_STRCMP(*argv, "uncompressed") == 0)
				form = POINT_CONVERSION_UNCOMPRESSED;
			else if (TINYCLR_SSL_STRCMP(*argv, "hybrid") == 0)
				form = POINT_CONVERSION_HYBRID;
			else
				goto bad;
			}
		else if (TINYCLR_SSL_STRCMP(*argv, "-param_enc") == 0)
			{
			if (--argc < 1)
				goto bad;
			++argv;
			new_asn1_flag = 1;
			if (TINYCLR_SSL_STRCMP(*argv, "named_curve") == 0)
				asn1_flag = OPENSSL_EC_NAMED_CURVE;
			else if (TINYCLR_SSL_STRCMP(*argv, "explicit") == 0)
				asn1_flag = 0;
			else
				goto bad;
			}
		else if (TINYCLR_SSL_STRCMP(*argv, "-param_out") == 0)
			param_out = 1;
		else if (TINYCLR_SSL_STRCMP(*argv, "-pubin") == 0)
			pubin=1;
		else if (TINYCLR_SSL_STRCMP(*argv, "-pubout") == 0)
			pubout=1;
		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
			{
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg     input format - "
				"DER or PEM\n");
		BIO_printf(bio_err, " -outform arg    output format - "
				"DER or PEM\n");
		BIO_printf(bio_err, " -in arg         input file\n");
		BIO_printf(bio_err, " -passin arg     input file pass "
				"phrase source\n");
		BIO_printf(bio_err, " -out arg        output file\n");
		BIO_printf(bio_err, " -passout arg    output file pass "
				"phrase source\n");
		BIO_printf(bio_err, " -engine e       use engine e, "
				"possibly a hardware device.\n");
		BIO_printf(bio_err, " -des            encrypt PEM output, "
				"instead of 'des' every other \n"
				"                 cipher "
				"supported by OpenSSL can be used\n");
		BIO_printf(bio_err, " -text           print the key\n");
		BIO_printf(bio_err, " -noout          don't print key out\n");
		BIO_printf(bio_err, " -param_out      print the elliptic "
				"curve parameters\n");
		BIO_printf(bio_err, " -conv_form arg  specifies the "
				"point conversion form \n");
		BIO_printf(bio_err, "                 possible values:"
				" compressed\n");
		BIO_printf(bio_err, "                                 "
				" uncompressed (default)\n");
		BIO_printf(bio_err, "                                  "
				" hybrid\n");
		BIO_printf(bio_err, " -param_enc arg  specifies the way"
				" the ec parameters are encoded\n");
		BIO_printf(bio_err, "                 in the asn1 der "
				"encoding\n");
		BIO_printf(bio_err, "                 possible values:"
				" named_curve (default)\n");
		BIO_printf(bio_err,"                                  "
				"explicit\n");
		goto end;
		}

	ERR_load_crypto_strings();

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine, 0);
#endif

	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) 
		{
		BIO_printf(bio_err, "Error getting passwords\n");
		goto end;
		}

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (infile == NULL)
		BIO_set_fp(in, OPENSSL_TYPE__FILE_STDIN, BIO_NOCLOSE);
	else
		{
		if (BIO_read_filename(in, infile) <= 0)
			{
			TINYCLR_SSL_PERROR(infile);
			goto end;
			}
		}

	BIO_printf(bio_err, "read EC key\n");
	if (informat == FORMAT_ASN1) 
		{
		if (pubin) 
			eckey = d2i_EC_PUBKEY_bio(in, NULL);
		else 
			eckey = d2i_ECPrivateKey_bio(in, NULL);
		} 
	else if (informat == FORMAT_PEM) 
		{
		if (pubin) 
			eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, 
				NULL);
		else 
			eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
				passin);
		} 
	else
		{
		BIO_printf(bio_err, "bad input format specified for key\n");
		goto end;
		}
	if (eckey == NULL)
		{
		BIO_printf(bio_err,"unable to load Key\n");
		ERR_print_errors(bio_err);
		goto end;
		}

	if (outfile == NULL)
		{
		BIO_set_fp(out, OPENSSL_TYPE__FILE_STDOUT, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			out = BIO_push(tmpbio, out);
			}
#endif
		}
	else
		{
		if (BIO_write_filename(out, outfile) <= 0)
			{
			TINYCLR_SSL_PERROR(outfile);
			goto end;
			}
		}

	group = EC_KEY_get0_group(eckey);

	if (new_form)
		EC_KEY_set_conv_form(eckey, form);

	if (new_asn1_flag)
		EC_KEY_set_asn1_flag(eckey, asn1_flag);

	if (text) 
		if (!EC_KEY_print(out, eckey, 0))
			{
			TINYCLR_SSL_PERROR(outfile);
			ERR_print_errors(bio_err);
			goto end;
			}

	if (noout) 
		{
		ret = 0;
		goto end;
		}

	BIO_printf(bio_err, "writing EC key\n");
	if (outformat == FORMAT_ASN1) 
		{
		if (param_out)
			i = i2d_ECPKParameters_bio(out, group);
		else if (pubin || pubout) 
			i = i2d_EC_PUBKEY_bio(out, eckey);
		else 
			i = i2d_ECPrivateKey_bio(out, eckey);
		} 
	else if (outformat == FORMAT_PEM) 
		{
		if (param_out)
			i = PEM_write_bio_ECPKParameters(out, group);
		else if (pubin || pubout)
			i = PEM_write_bio_EC_PUBKEY(out, eckey);
		else 
			i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
						NULL, 0, NULL, passout);
		} 
	else 
		{
		BIO_printf(bio_err, "bad output format specified for "
			"outfile\n");
		goto end;
		}

	if (!i)
		{
		BIO_printf(bio_err, "unable to write private key\n");
		ERR_print_errors(bio_err);
		}
	else
		ret=0;
end:
	if (in)
		BIO_free(in);
	if (out)
		BIO_free_all(out);
	if (eckey)
		EC_KEY_free(eckey);
	if (passin)
		OPENSSL_free(passin);
	if (passout)
		OPENSSL_free(passout);
	apps_shutdown();
	OPENSSL_EXIT(ret);
}
Exemple #21
0
int
dsaparam_main(int argc, char **argv)
{
	DSA *dsa = NULL;
	int i, badops = 0, text = 0;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, noout = 0, C = 0, ret = 1;
	char *infile, *outfile, *prog;
	int numbits = -1, num, genkey = 0;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
#ifdef GENCB_TEST
	const char *errstr = NULL;
	int timebomb = 0;
#endif

	infile = NULL;
	outfile = NULL;
	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		}
#endif
#ifdef GENCB_TEST
		else if (strcmp(*argv, "-timebomb") == 0) {
			if (--argc < 1)
				goto bad;
			timebomb = strtonum(*(++argv), 0, INT_MAX, &errstr);
			if (errstr)
				goto bad;
		}
#endif
		else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-genkey") == 0) {
			genkey = 1;
		} else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else if (sscanf(*argv, "%d", &num) == 1) {
			/* generate a key */
			numbits = num;
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] [bits] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg   input format - DER or PEM\n");
		BIO_printf(bio_err, " -outform arg  output format - DER or PEM\n");
		BIO_printf(bio_err, " -in arg       input file\n");
		BIO_printf(bio_err, " -out arg      output file\n");
		BIO_printf(bio_err, " -text         print as text\n");
		BIO_printf(bio_err, " -C            Output C code\n");
		BIO_printf(bio_err, " -noout        no output\n");
		BIO_printf(bio_err, " -genkey       generate a DSA key\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, " -engine e     use engine e, possibly a hardware device.\n");
#endif
#ifdef GENCB_TEST
		BIO_printf(bio_err, " -timebomb n   interrupt keygen after <n> seconds\n");
#endif
		BIO_printf(bio_err, " number        number of bits to use for generating private key\n");
		goto end;
	}
	ERR_load_crypto_strings();

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if (numbits > 0) {
		BN_GENCB cb;
		BN_GENCB_set(&cb, dsa_cb, bio_err);
		dsa = DSA_new();
		if (!dsa) {
			BIO_printf(bio_err, "Error allocating DSA object\n");
			goto end;
		}
		BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
		BIO_printf(bio_err, "This could take some time\n");
#ifdef GENCB_TEST
		if (timebomb > 0) {
			struct sigaction act;
			act.sa_handler = timebomb_sigalarm;
			act.sa_flags = 0;
			BIO_printf(bio_err, "(though I'll stop it if not done within %d secs)\n",
			    timebomb);
			if (sigaction(SIGALRM, &act, NULL) != 0) {
				BIO_printf(bio_err, "Error, couldn't set SIGALRM handler\n");
				goto end;
			}
			alarm(timebomb);
		}
#endif
		if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) {
#ifdef GENCB_TEST
			if (stop_keygen_flag) {
				BIO_printf(bio_err, "DSA key generation time-stopped\n");
				/* This is an asked-for behaviour! */
				ret = 0;
				goto end;
			}
#endif
			ERR_print_errors(bio_err);
			BIO_printf(bio_err, "Error, DSA key generation failed\n");
			goto end;
		}
	} else if (informat == FORMAT_ASN1)
		dsa = d2i_DSAparams_bio(in, NULL);
	else if (informat == FORMAT_PEM)
		dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
	else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}
	if (dsa == NULL) {
		BIO_printf(bio_err, "unable to load DSA parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (text) {
		DSAparams_print(out, dsa);
	}
	if (C) {
		unsigned char *data;
		int l, len, bits_p;

		len = BN_num_bytes(dsa->p);
		bits_p = BN_num_bits(dsa->p);
		data = malloc(len + 20);
		if (data == NULL) {
			perror("malloc");
			goto end;
		}
		l = BN_bn2bin(dsa->p, data);
		printf("static unsigned char dsa%d_p[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dsa->q, data);
		printf("static unsigned char dsa%d_q[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dsa->g, data);
		printf("static unsigned char dsa%d_g[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		free(data);
		printf("\n\t};\n\n");

		printf("DSA *get_dsa%d()\n\t{\n", bits_p);
		printf("\tDSA *dsa;\n\n");
		printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n");
		printf("\tdsa->p = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n",
		    bits_p, bits_p);
		printf("\tdsa->q = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n",
		    bits_p, bits_p);
		printf("\tdsa->g = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n",
		    bits_p, bits_p);
		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
		printf("\treturn(dsa);\n\t}\n");
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_DSAparams_bio(out, dsa);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_DSAparams(out, dsa);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write DSA parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (genkey) {
		DSA *dsakey;

		if ((dsakey = DSAparams_dup(dsa)) == NULL)
			goto end;
		if (!DSA_generate_key(dsakey)) {
			ERR_print_errors(bio_err);
			DSA_free(dsakey);
			goto end;
		}
		if (outformat == FORMAT_ASN1)
			i = i2d_DSAPrivateKey_bio(out, dsakey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			DSA_free(dsakey);
			goto end;
		}
		DSA_free(dsakey);
	}
	ret = 0;

end:
	BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (dsa != NULL)
		DSA_free(dsa);

	return (ret);
}
Exemple #22
0
int MAIN(int argc, char **argv)
	{
	EC_GROUP *group = NULL;
	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; 
	int 	new_form = 0;
	int 	asn1_flag = OPENSSL_EC_NAMED_CURVE;
	int 	new_asn1_flag = 0;
	char 	*curve_name = NULL, *inrand = NULL;
	int	list_curves = 0, no_seed = 0, check = 0,
		badops = 0, text = 0, i, need_rand = 0, genkey = 0;
	char	*infile = NULL, *outfile = NULL, *prog;
	BIO 	*in = NULL, *out = NULL;
	int 	informat, outformat, noout = 0, C = 0, ret = 1;
#ifndef OPENSSL_NO_ENGINE
	ENGINE	*e = NULL;
#endif
	char	*engine = NULL;

	BIGNUM	*ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
		*ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
	unsigned char *buffer = NULL;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	prog=argv[0];
	argc--;
	argv++;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-text") == 0)
			text = 1;
		else if (strcmp(*argv,"-C") == 0)
			C = 1;
		else if (strcmp(*argv,"-check") == 0)
			check = 1;
		else if (strcmp (*argv, "-name") == 0)
			{
			if (--argc < 1)
				goto bad;
			curve_name = *(++argv);
			}
		else if (strcmp(*argv, "-list_curves") == 0)
			list_curves = 1;
		else if (strcmp(*argv, "-conv_form") == 0)
			{
			if (--argc < 1)
				goto bad;
			++argv;
			new_form = 1;
			if (strcmp(*argv, "compressed") == 0)
				form = POINT_CONVERSION_COMPRESSED;
			else if (strcmp(*argv, "uncompressed") == 0)
				form = POINT_CONVERSION_UNCOMPRESSED;
			else if (strcmp(*argv, "hybrid") == 0)
				form = POINT_CONVERSION_HYBRID;
			else
				goto bad;
			}
		else if (strcmp(*argv, "-param_enc") == 0)
			{
			if (--argc < 1)
				goto bad;
			++argv;
			new_asn1_flag = 1;
			if (strcmp(*argv, "named_curve") == 0)
				asn1_flag = OPENSSL_EC_NAMED_CURVE;
			else if (strcmp(*argv, "explicit") == 0)
				asn1_flag = 0;
			else
				goto bad;
			}
		else if (strcmp(*argv, "-no_seed") == 0)
			no_seed = 1;
		else if (strcmp(*argv, "-noout") == 0)
			noout=1;
		else if (strcmp(*argv,"-genkey") == 0)
			{
			genkey=1;
			need_rand=1;
			}
		else if (strcmp(*argv, "-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			need_rand=1;
			}
		else if(strcmp(*argv, "-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine = *(++argv);
			}	
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg       input format - "
				"default PEM (DER or PEM)\n");
		BIO_printf(bio_err, " -outform arg      output format - "
				"default PEM\n");
		BIO_printf(bio_err, " -in  arg          input file  - "
				"default stdin\n");
		BIO_printf(bio_err, " -out arg          output file - "
				"default stdout\n");
		BIO_printf(bio_err, " -noout            do not print the "
				"ec parameter\n");
		BIO_printf(bio_err, " -text             print the ec "
				"parameters in text form\n");
		BIO_printf(bio_err, " -check            validate the ec "
				"parameters\n");
		BIO_printf(bio_err, " -C                print a 'C' "
				"function creating the parameters\n");
		BIO_printf(bio_err, " -name arg         use the "
				"ec parameters with 'short name' name\n");
		BIO_printf(bio_err, " -list_curves      prints a list of "
				"all currently available curve 'short names'\n");
		BIO_printf(bio_err, " -conv_form arg    specifies the "
				"point conversion form \n");
		BIO_printf(bio_err, "                   possible values:"
				" compressed\n");
		BIO_printf(bio_err, "                                   "
				" uncompressed (default)\n");
		BIO_printf(bio_err, "                                   "
				" hybrid\n");
		BIO_printf(bio_err, " -param_enc arg    specifies the way"
				" the ec parameters are encoded\n");
		BIO_printf(bio_err, "                   in the asn1 der "
				"encoding\n");
		BIO_printf(bio_err, "                   possible values:"
				" named_curve (default)\n");
		BIO_printf(bio_err, "                                   "
				" explicit\n");
		BIO_printf(bio_err, " -no_seed          if 'explicit'"
				" parameters are choosen do not"
				" use the seed\n");
		BIO_printf(bio_err, " -genkey           generate ec"
				" key\n");
		BIO_printf(bio_err, " -rand file        files to use for"
				" random number input\n");
		BIO_printf(bio_err, " -engine e         use engine e, "
				"possibly a hardware device\n");
		goto end;
		}

	ERR_load_crypto_strings();

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (infile == NULL)
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
	else
		{
		if (BIO_read_filename(in,infile) <= 0)
			{
			perror(infile);
			goto end;
			}
		}
	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outfile) <= 0)
			{
			perror(outfile);
			goto end;
			}
		}

#ifndef OPENSSL_NO_ENGINE
	e = setup_engine(bio_err, engine, 0);
#endif

	if (list_curves)
		{
		EC_builtin_curve *curves = NULL;
		size_t crv_len = 0;
		size_t n = 0;

		crv_len = EC_get_builtin_curves(NULL, 0);

		curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));

		if (curves == NULL)
			goto end;

		if (!EC_get_builtin_curves(curves, crv_len))
			{
			OPENSSL_free(curves);
			goto end;
			}

		
		for (n = 0; n < crv_len; n++)
			{
			const char *comment;
			const char *sname;
			comment = curves[n].comment;
			sname   = OBJ_nid2sn(curves[n].nid);
			if (comment == NULL)
				comment = "CURVE DESCRIPTION NOT AVAILABLE";
			if (sname == NULL)
				sname = "";

			BIO_printf(out, "  %-10s: ", sname);
			BIO_printf(out, "%s\n", comment);
			} 

		OPENSSL_free(curves);
		ret = 0;
		goto end;
		}

	if (curve_name != NULL)
		{
		int nid;

		/* workaround for the SECG curve names secp192r1
		 * and secp256r1 (which are the same as the curves
		 * prime192v1 and prime256v1 defined in X9.62)
		 */
		if (!strcmp(curve_name, "secp192r1"))
			{
			BIO_printf(bio_err, "using curve name prime192v1 "
				"instead of secp192r1\n");
			nid = NID_X9_62_prime192v1;
			}
		else if (!strcmp(curve_name, "secp256r1"))
			{
			BIO_printf(bio_err, "using curve name prime256v1 "
				"instead of secp256r1\n");
			nid = NID_X9_62_prime256v1;
			}
		else
			nid = OBJ_sn2nid(curve_name);
	
		if (nid == 0)
			{
			BIO_printf(bio_err, "unknown curve name (%s)\n", 
				curve_name);
			goto end;
			}

		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL)
			{
			BIO_printf(bio_err, "unable to create curve (%s)\n", 
				curve_name);
			goto end;
			}
		EC_GROUP_set_asn1_flag(group, asn1_flag);
		EC_GROUP_set_point_conversion_form(group, form);
		}
	else if (informat == FORMAT_ASN1)
		{
		group = d2i_ECPKParameters_bio(in, NULL);
		}
	else if (informat == FORMAT_PEM)
		{
		group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
		}
	else
		{
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
		}

	if (group == NULL)
		{
		BIO_printf(bio_err, 
			"unable to load elliptic curve parameters\n");
		ERR_print_errors(bio_err);
		goto end;
		}

	if (new_form)
		EC_GROUP_set_point_conversion_form(group, form);

	if (new_asn1_flag)
		EC_GROUP_set_asn1_flag(group, asn1_flag);

	if (no_seed)
		{
		EC_GROUP_set_seed(group, NULL, 0);
		}

	if (text)
		{
		if (!ECPKParameters_print(out, group, 0))
			goto end;
		}

	if (check)
		{
		if (group == NULL)
			BIO_printf(bio_err, "no elliptic curve parameters\n");
		BIO_printf(bio_err, "checking elliptic curve parameters: ");
		if (!EC_GROUP_check(group, NULL))
			{
			BIO_printf(bio_err, "failed\n");
			ERR_print_errors(bio_err);
			}
		else
			BIO_printf(bio_err, "ok\n");
			
		}

	if (C)
		{
		size_t	buf_len = 0, tmp_len = 0;
		const EC_POINT *point;
		int	is_prime, len = 0;
		const EC_METHOD *meth = EC_GROUP_method_of(group);

		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
		    (ec_order = BN_new()) == NULL || 
		    (ec_cofactor = BN_new()) == NULL )
			{
			perror("OPENSSL_malloc");
			goto end;
			}

		is_prime = (EC_METHOD_get_field_type(meth) == 
			NID_X9_62_prime_field);

		if (is_prime)
			{
			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
				ec_b, NULL))
				goto end;
			}
		else
			{
			/* TODO */
			goto end;
			}

		if ((point = EC_GROUP_get0_generator(group)) == NULL)
			goto end;
		if (!EC_POINT_point2bn(group, point, 
			EC_GROUP_get_point_conversion_form(group), ec_gen, 
			NULL))
			goto end;
		if (!EC_GROUP_get_order(group, ec_order, NULL))
			goto end;
		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
			goto end;

		if (!ec_p || !ec_a || !ec_b || !ec_gen || 
			!ec_order || !ec_cofactor)
			goto end;

		len = BN_num_bits(ec_order);

		if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
			buf_len = tmp_len;

		buffer = (unsigned char *)OPENSSL_malloc(buf_len);

		if (buffer == NULL)
			{
			perror("OPENSSL_malloc");
			goto end;
			}

		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len, 
			buffer);

		BIO_printf(out, "\n\n");

		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
		BIO_printf(out, "\tint ok=0;\n");
		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
				"*tmp_3 = NULL;\n\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
				"sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
				"goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
				"sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
				"goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
				"sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
				"goto err;\n", len, len);
		if (is_prime)
			{
			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
				"GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
				"\n\t\tgoto err;\n\n");
			}
		else
			{
			/* TODO */
			goto end;
			}
		BIO_printf(out, "\t/* build generator */\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
				"sizeof(ec_gen_%d), tmp_1)) == NULL)"
				"\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
				"NULL, NULL);\n");
		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
				"sizeof(ec_order_%d), tmp_2)) == NULL)"
				"\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
				"sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
				"\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
				" tmp_2, tmp_3))\n\t\tgoto err;\n");
		BIO_printf(out, "\n\tok=1;\n");
		BIO_printf(out, "err:\n");
		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
		BIO_printf(out, "\tif (!ok)\n");
		BIO_printf(out, "\t\t{\n");
		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
		BIO_printf(out, "\t\tgroup = NULL;\n");
		BIO_printf(out, "\t\t}\n");
		BIO_printf(out, "\treturn(group);\n\t}\n");
	}

	if (!noout)
		{
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPKParameters_bio(out, group);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPKParameters(out, group);
		else	
			{
			BIO_printf(bio_err,"bad output format specified for"
				" outfile\n");
			goto end;
			}
		if (!i)
			{
			BIO_printf(bio_err, "unable to write elliptic "
				"curve parameters\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	
	if (need_rand)
		{
		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
		if (inrand != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				app_RAND_load_files(inrand));
		}

	if (genkey)
		{
		EC_KEY *eckey = EC_KEY_new();

		if (eckey == NULL)
			goto end;

		assert(need_rand);

		if (EC_KEY_set_group(eckey, group) == 0)
			goto end;
		
		if (!EC_KEY_generate_key(eckey))
			{
			EC_KEY_free(eckey);
			goto end;
			}
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPrivateKey_bio(out, eckey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
				NULL, 0, NULL, NULL);
		else	
			{
			BIO_printf(bio_err, "bad output format specified "
				"for outfile\n");
			EC_KEY_free(eckey);
			goto end;
			}
		EC_KEY_free(eckey);
		}

	if (need_rand)
		app_RAND_write_file(NULL, bio_err);

	ret=0;
end:
	if (ec_p)
		BN_free(ec_p);
	if (ec_a)
		BN_free(ec_a);
	if (ec_b)
		BN_free(ec_b);
	if (ec_gen)
		BN_free(ec_gen);
	if (ec_order)
		BN_free(ec_order);
	if (ec_cofactor)
		BN_free(ec_cofactor);
	if (buffer)
		OPENSSL_free(buffer);
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (group != NULL)
		EC_GROUP_free(group);
	apps_shutdown();
	OPENSSL_EXIT(ret);
}
Exemple #23
0
int main ()
{
    int err;

    int sig_len;

    unsigned char sig_buf[4096];

    static char certfile[] = "cert.pem";

    static char keyfile[] = "key.pem";

    static char data[] = "I owe you...";

    EVP_MD_CTX md_ctx;

    EVP_PKEY *pkey;

    FILE *fp;

    X509 *x509;

    /* Just load the crypto library error strings,
     * SSL_load_error_strings() loads the crypto AND the SSL ones */
    /* SSL_load_error_strings(); */
    ERR_load_crypto_strings ();

    /* Read private key */

    fp = fopen (keyfile, "r");
    if (fp == NULL)
        exit (1);
    pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL);
    fclose (fp);

    if (pkey == NULL)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    /* Do the signature */

    EVP_SignInit (&md_ctx, EVP_sha1 ());
    EVP_SignUpdate (&md_ctx, data, strlen (data));
    sig_len = sizeof (sig_buf);
    err = EVP_SignFinal (&md_ctx, sig_buf, &sig_len, pkey);

    if (err != 1)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    EVP_PKEY_free (pkey);

    /* Read public key */

    fp = fopen (certfile, "r");
    if (fp == NULL)
        exit (1);
    x509 = PEM_read_X509 (fp, NULL, NULL, NULL);
    fclose (fp);

    if (x509 == NULL)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    /* Get public key - eay */
    pkey = X509_get_pubkey (x509);
    if (pkey == NULL)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }

    /* Verify the signature */

    EVP_VerifyInit (&md_ctx, EVP_sha1 ());
    EVP_VerifyUpdate (&md_ctx, data, strlen ((char *) data));
    err = EVP_VerifyFinal (&md_ctx, sig_buf, sig_len, pkey);
    EVP_PKEY_free (pkey);

    if (err != 1)
    {
        ERR_print_errors_fp (stderr);
        exit (1);
    }
    printf ("Signature Verified Ok.\n");
    return (0);
}
int MAIN(int argc, char **argv)
	{
	DSA *dsa=NULL;
	int i,badops=0,text=0;
	BIO *in=NULL,*out=NULL;
	int informat,outformat,noout=0,C=0,ret=1;
	char *infile,*outfile,*prog,*inrand=NULL;
	int numbits= -1,num,genkey=0;
	int need_rand=0;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	infile=NULL;
	outfile=NULL;
	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	prog=argv[0];
	argc--;
	argv++;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-text") == 0)
			text=1;
		else if (strcmp(*argv,"-C") == 0)
			C=1;
		else if (strcmp(*argv,"-genkey") == 0)
			{
			genkey=1;
			need_rand=1;
			}
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			need_rand=1;
			}
		else if (strcmp(*argv,"-noout") == 0)
			noout=1;
		else if (sscanf(*argv,"%d",&num) == 1)
			{
			/* generate a key */
			numbits=num;
			need_rand=1;
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg   input format - DER or PEM\n");
		BIO_printf(bio_err," -outform arg  output format - DER or PEM\n");
		BIO_printf(bio_err," -in arg       input file\n");
		BIO_printf(bio_err," -out arg      output file\n");
		BIO_printf(bio_err," -text         print as text\n");
		BIO_printf(bio_err," -C            Output C code\n");
		BIO_printf(bio_err," -noout        no output\n");
		BIO_printf(bio_err," -rand         files to use for random number input\n");
		BIO_printf(bio_err," number        number of bits to use for generating private key\n");
		goto end;
		}

	ERR_load_crypto_strings();

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (infile == NULL)
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
	else
		{
		if (BIO_read_filename(in,infile) <= 0)
			{
			perror(infile);
			goto end;
			}
		}
	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outfile) <= 0)
			{
			perror(outfile);
			goto end;
			}
		}

	if (need_rand)
		{
		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
		if (inrand != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				app_RAND_load_files(inrand));
		}

	if (numbits > 0)
		{
		assert(need_rand);
		BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
	        BIO_printf(bio_err,"This could take some time\n");
	        dsa=DSA_generate_parameters(num,NULL,0,NULL,NULL, dsa_cb,bio_err);
		}
	else if	(informat == FORMAT_ASN1)
		dsa=d2i_DSAparams_bio(in,NULL);
	else if (informat == FORMAT_PEM)
		dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
	else
		{
		BIO_printf(bio_err,"bad input format specified\n");
		goto end;
		}
	if (dsa == NULL)
		{
		BIO_printf(bio_err,"unable to load DSA parameters\n");
		ERR_print_errors(bio_err);
		goto end;
		}

	if (text)
		{
		DSAparams_print(out,dsa);
		}
	
	if (C)
		{
		unsigned char *data;
		int l,len,bits_p,bits_q,bits_g;

		len=BN_num_bytes(dsa->p);
		bits_p=BN_num_bits(dsa->p);
		bits_q=BN_num_bits(dsa->q);
		bits_g=BN_num_bits(dsa->g);
		data=(unsigned char *)OPENSSL_malloc(len+20);
		if (data == NULL)
			{
			perror("OPENSSL_malloc");
			goto end;
			}
		l=BN_bn2bin(dsa->p,data);
		printf("static unsigned char dsa%d_p[]={",bits_p);
		for (i=0; i<l; i++)
			{
			if ((i%12) == 0) printf("\n\t");
			printf("0x%02X,",data[i]);
			}
		printf("\n\t};\n");

		l=BN_bn2bin(dsa->q,data);
		printf("static unsigned char dsa%d_q[]={",bits_p);
		for (i=0; i<l; i++)
			{
			if ((i%12) == 0) printf("\n\t");
			printf("0x%02X,",data[i]);
			}
		printf("\n\t};\n");

		l=BN_bn2bin(dsa->g,data);
		printf("static unsigned char dsa%d_g[]={",bits_p);
		for (i=0; i<l; i++)
			{
			if ((i%12) == 0) printf("\n\t");
			printf("0x%02X,",data[i]);
			}
		printf("\n\t};\n\n");

		printf("DSA *get_dsa%d()\n\t{\n",bits_p);
		printf("\tDSA *dsa;\n\n");
		printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n");
		printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n",
			bits_p,bits_p);
		printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n",
			bits_p,bits_p);
		printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n",
			bits_p,bits_p);
		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
		printf("\treturn(dsa);\n\t}\n");
		}


	if (!noout)
		{
		if 	(outformat == FORMAT_ASN1)
			i=i2d_DSAparams_bio(out,dsa);
		else if (outformat == FORMAT_PEM)
			i=PEM_write_bio_DSAparams(out,dsa);
		else	{
			BIO_printf(bio_err,"bad output format specified for outfile\n");
			goto end;
			}
		if (!i)
			{
			BIO_printf(bio_err,"unable to write DSA parameters\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	if (genkey)
		{
		DSA *dsakey;

		assert(need_rand);
		if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
		if (!DSA_generate_key(dsakey)) goto end;
		if 	(outformat == FORMAT_ASN1)
			i=i2d_DSAPrivateKey_bio(out,dsakey);
		else if (outformat == FORMAT_PEM)
			i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
		else	{
			BIO_printf(bio_err,"bad output format specified for outfile\n");
			goto end;
			}
		DSA_free(dsakey);
		}
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
	ret=0;
end:
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (dsa != NULL) DSA_free(dsa);
	EXIT(ret);
	}
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL;
    char *infile=NULL, *outfile=NULL, *keyname = NULL;	
    char *certfile=NULL;
    BIO *in=NULL, *out = NULL;
    char **args;
    char *name = NULL;
    char *csp_name = NULL;
    PKCS12 *p12 = NULL;
    char pass[50], macpass[50];
    int export_cert = 0;
    int options = 0;
    int chain = 0;
    int badarg = 0;
    int iter = PKCS12_DEFAULT_ITER;
    int maciter = PKCS12_DEFAULT_ITER;
    int twopass = 0;
    int keytype = 0;
    int cert_pbe;
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int ret = 1;
    int macver = 1;
    int noprompt = 0;
    STACK *canames = NULL;
    char *cpass = NULL, *mpass = NULL;
    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
    char *passin = NULL, *passout = NULL;
    char *inrand = NULL;
    char *CApath = NULL, *CAfile = NULL;
#ifndef OPENSSL_NO_ENGINE
    char *engine=NULL;
#endif

    apps_startup();

#ifdef OPENSSL_FIPS
    if (FIPS_mode())
	cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    else
#endif
    cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;

    enc = EVP_des_ede3_cbc();
    if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;

    args = argv + 1;


    while (*args) {
	if (*args[0] == '-') {
		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
		else if (!strcmp (*args, "-info")) options |= INFO;
		else if (!strcmp (*args, "-chain")) chain = 1;
		else if (!strcmp (*args, "-twopass")) twopass = 1;
		else if (!strcmp (*args, "-nomacver")) macver = 0;
		else if (!strcmp (*args, "-descert"))
    			cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
		else if (!strcmp (*args, "-export")) export_cert = 1;
		else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
#ifndef OPENSSL_NO_IDEA
		else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
#endif
		else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
#ifndef OPENSSL_NO_AES
		else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
		else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
		else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
#endif
		else if (!strcmp (*args, "-noiter")) iter = 1;
		else if (!strcmp (*args, "-maciter"))
					 maciter = PKCS12_DEFAULT_ITER;
		else if (!strcmp (*args, "-nomaciter"))
					 maciter = 1;
		else if (!strcmp (*args, "-nodes")) enc=NULL;
		else if (!strcmp (*args, "-certpbe")) {
			if (args[1]) {
				args++;
				cert_pbe=OBJ_txt2nid(*args);
				if(cert_pbe == NID_undef) {
					BIO_printf(bio_err,
						 "Unknown PBE algorithm %s\n", *args);
					badarg = 1;
				}
			} else badarg = 1;
		} else if (!strcmp (*args, "-keypbe")) {
			if (args[1]) {
				args++;
				key_pbe=OBJ_txt2nid(*args);
				if(key_pbe == NID_undef) {
					BIO_printf(bio_err,
						 "Unknown PBE algorithm %s\n", *args);
					badarg = 1;
				}
			} else badarg = 1;
		} else if (!strcmp (*args, "-rand")) {
		    if (args[1]) {
			args++;	
			inrand = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-inkey")) {
		    if (args[1]) {
			args++;	
			keyname = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-certfile")) {
		    if (args[1]) {
			args++;	
			certfile = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-name")) {
		    if (args[1]) {
			args++;	
			name = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-CSP")) {
		    if (args[1]) {
			args++;	
			csp_name = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-caname")) {
		    if (args[1]) {
			args++;	
			if (!canames) canames = sk_new_null();
			sk_push(canames, *args);
		    } else badarg = 1;
		} else if (!strcmp (*args, "-in")) {
		    if (args[1]) {
			args++;	
			infile = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-out")) {
		    if (args[1]) {
			args++;	
			outfile = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-passin")) {
		    if (args[1]) {
			args++;	
			passargin = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-passout")) {
		    if (args[1]) {
			args++;	
			passargout = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-password")) {
		    if (args[1]) {
			args++;	
			passarg = *args;
		    	noprompt = 1;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-CApath")) {
		    if (args[1]) {
			args++;	
			CApath = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-CAfile")) {
		    if (args[1]) {
			args++;	
			CAfile = *args;
		    } else badarg = 1;
#ifndef OPENSSL_NO_ENGINE
		} else if (!strcmp(*args,"-engine")) {
		    if (args[1]) {
			args++;	
			engine = *args;
		    } else badarg = 1;
#endif
		} else badarg = 1;

	} else badarg = 1;
	args++;
    }

    if (badarg) {
	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
	BIO_printf (bio_err, "where options are\n");
	BIO_printf (bio_err, "-export       output PKCS12 file\n");
	BIO_printf (bio_err, "-chain        add certificate chain\n");
	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
	BIO_printf (bio_err, "-in  infile   input filename\n");
	BIO_printf (bio_err, "-out outfile  output filename\n");
	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
#ifndef OPENSSL_NO_IDEA
	BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
#endif
#ifndef OPENSSL_NO_AES
	BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
	BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
#endif
	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
	BIO_printf (bio_err, "-password p   set import/export password source\n");
	BIO_printf (bio_err, "-passin p     input file pass phrase source\n");
	BIO_printf (bio_err, "-passout p    output file pass phrase source\n");
#ifndef OPENSSL_NO_ENGINE
	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
#endif
	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
	BIO_printf(bio_err,  "              the random number generator\n");
    	goto end;
    }

#ifndef OPENSSL_NO_ENGINE
    e = setup_engine(bio_err, engine, 0);
#endif

    if(passarg) {
	if(export_cert) passargout = passarg;
	else passargin = passarg;
    }

    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
	BIO_printf(bio_err, "Error getting passwords\n");
	goto end;
    }

    if(!cpass) {
    	if(export_cert) cpass = passout;
    	else cpass = passin;
    }

    if(cpass) {
	mpass = cpass;
	noprompt = 1;
    } else {
	cpass = pass;
	mpass = macpass;
    }

    if(export_cert || inrand) {
    	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));
    }
    ERR_load_crypto_strings();

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read files");
#endif

    if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
    else in = BIO_new_file(infile, "rb");
    if (!in) {
	    BIO_printf(bio_err, "Error opening input file %s\n",
						infile ? infile : "<stdin>");
	    perror (infile);
	    goto end;
   }

#if 0
   if (certfile) {
    	if(!(certsin = BIO_new_file(certfile, "r"))) {
	    BIO_printf(bio_err, "Can't open certificate file %s\n", certfile);
	    perror (certfile);
	    goto end;
	}
    }

    if (keyname) {
    	if(!(inkey = BIO_new_file(keyname, "r"))) {
	    BIO_printf(bio_err, "Can't key certificate file %s\n", keyname);
	    perror (keyname);
	    goto end;
	}
     }
#endif

#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
    CRYPTO_push_info("write files");
#endif

    if (!outfile) {
	out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	    out = BIO_push(tmpbio, out);
	}
#endif
    } else out = BIO_new_file(outfile, "wb");
    if (!out) {
	BIO_printf(bio_err, "Error opening output file %s\n",
						outfile ? outfile : "<stdout>");
	perror (outfile);
	goto end;
    }
    if (twopass) {
#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read MAC password");
#endif
	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
    	    goto end;
       	}
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    }

    if (export_cert) {
	EVP_PKEY *key = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	PKCS8_PRIV_KEY_INFO *p8 = NULL;
	PKCS7 *authsafe = NULL;
	X509 *ucert = NULL;
	STACK_OF(X509) *certs=NULL;
	char *catmp = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen = 0;

#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("process -export_cert");
	CRYPTO_push_info("reading private key");
#endif
	key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1,
		passin, e, "private key");
	if (!key) {
		goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input");
#endif

	/* Load in all certs in input file */
	if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
		"certificates"))) {
		goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input 2");
#endif

	for(i = 0; i < sk_X509_num(certs); i++) {
		ucert = sk_X509_value(certs, i);
		if(X509_check_private_key(ucert, key)) {
			X509_digest(ucert, EVP_sha1(), keyid, &keyidlen);
			break;
		}
	}
	if(!keyidlen) {
		ucert = NULL;
		BIO_printf(bio_err, "No certificate matches private key\n");
		goto export_end;
	}
	
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from certfile");
#endif

	bags = sk_PKCS12_SAFEBAG_new_null ();

	/* Add any more certificates asked for */
	if (certfile) {
		STACK_OF(X509) *morecerts=NULL;
		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
					    NULL, e,
					    "certificates from certfile"))) {
			goto export_end;
		}
		while(sk_X509_num(morecerts) > 0) {
			sk_X509_push(certs, sk_X509_shift(morecerts));
		}
		sk_X509_free(morecerts);
 	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building chain");
#endif

	/* If chaining get chain from user cert */
	if (chain) {
        	int vret;
		STACK_OF(X509) *chain2;
		X509_STORE *store = X509_STORE_new();
		if (!store)
			{
			BIO_printf (bio_err, "Memory allocation error\n");
			goto export_end;
			}
		if (!X509_STORE_load_locations(store, CAfile, CApath))
			X509_STORE_set_default_paths (store);

		vret = get_cert_chain (ucert, store, &chain2);
		X509_STORE_free(store);

		if (!vret) {
		    /* Exclude verified certificate */
		    for (i = 1; i < sk_X509_num (chain2) ; i++) 
			sk_X509_push(certs, sk_X509_value (chain2, i));
		    /* Free first certificate */
		    X509_free(sk_X509_value(chain2, 0));
		    sk_X509_free(chain2);
		} else {
			BIO_printf (bio_err, "Error %s getting chain.\n",
					X509_verify_cert_error_string(vret));
			goto export_end;
		}			
    	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building bags");
#endif

	/* We now have loads of certificates: include them all */
	for(i = 0; i < sk_X509_num(certs); i++) {
		X509 *cert = NULL;
		cert = sk_X509_value(certs, i);
		bag = PKCS12_x5092certbag(cert);
		/* If it matches private key set id */
		if(cert == ucert) {
			if(name) PKCS12_add_friendlyname(bag, name, -1);
			PKCS12_add_localkeyid(bag, keyid, keyidlen);
		} else if((catmp = sk_shift(canames))) 
				PKCS12_add_friendlyname(bag, catmp, -1);
		sk_PKCS12_SAFEBAG_push(bags, bag);
	}
	sk_X509_pop_free(certs, X509_free);
	certs = NULL;

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting bags");
#endif

	if(!noprompt &&
		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
	    goto export_end;
        }
	if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
	/* Turn certbags into encrypted authsafe */
	authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0,
								 iter, bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	if (!authsafe) {
		ERR_print_errors (bio_err);
		goto export_end;
	}

	safes = sk_PKCS7_new_null ();
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building shrouded key bag");
#endif

	/* Make a shrouded key bag */
	p8 = EVP_PKEY2PKCS8 (key);
	if(keytype) PKCS8_add_keyusage(p8, keytype);
	bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8);
	PKCS8_PRIV_KEY_INFO_free(p8);
	p8 = NULL;
        if (name) PKCS12_add_friendlyname (bag, name, -1);
	if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1);
	PKCS12_add_localkeyid (bag, keyid, keyidlen);
	bags = sk_PKCS12_SAFEBAG_new_null();
	sk_PKCS12_SAFEBAG_push (bags, bag);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting shrouded key bag");
#endif

	/* Turn it into unencrypted safe bag */
	authsafe = PKCS12_pack_p7data (bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building pkcs12");
#endif

	p12 = PKCS12_init(NID_pkcs7_data);

	PKCS12_pack_authsafes(p12, safes);

	sk_PKCS7_pop_free(safes, PKCS7_free);
	safes = NULL;

	PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("writing pkcs12");
#endif

	i2d_PKCS12_bio (out, p12);

	ret = 0;

    export_end:
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_pop_info();
	CRYPTO_push_info("process -export_cert: freeing");
#endif

	if (key) EVP_PKEY_free(key);
	if (certs) sk_X509_pop_free(certs, X509_free);
	if (safes) sk_PKCS7_pop_free(safes, PKCS7_free);
	if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif
	goto end;
	
    }

    if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
	ERR_print_errors(bio_err);
	goto end;
    }

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read import password");
#endif
    if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
	goto end;
    }
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif

    if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);

    if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
    if(macver) {
#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("verify MAC");
#endif
	/* If we enter empty password try no password first */
	if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
		/* If mac and crypto pass the same set it to NULL too */
		if(!twopass) cpass = NULL;
	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
	    ERR_print_errors (bio_err);
	    goto end;
	}
	BIO_printf (bio_err, "MAC verified OK\n");
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    }

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("output keys and certificates");
#endif
    if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
	BIO_printf(bio_err, "Error outputting keys and certificates\n");
	ERR_print_errors (bio_err);
	goto end;
    }
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    ret = 0;
 end:
    if (p12) PKCS12_free(p12);
    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
#ifdef CRYPTO_MDEBUG
    CRYPTO_remove_all_info();
#endif
    BIO_free(in);
    BIO_free_all(out);
    if (canames) sk_free(canames);
    if(passin) OPENSSL_free(passin);
    if(passout) OPENSSL_free(passout);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemple #26
0
int enc_main(const int argc, const char *argv[]) {
	//fprintf(stderr, "Calling encryption main with args:\n");

	if (argc < 4) {
		fprintf(stderr, "Insufficient arguments.");
		printUsage();
	}

	const char *startup_path = argv[0];
	const char *cipher_name = argv[1];
	const char *digest_name = argv[2];
	const char *rootDir = argv[3];

	int maxKey = 0;

	int i = 0;
	for (i = 0; i < argc; i++) {
		char arg[strlen(argv[i]) + 1];
		strcpy(arg, argv[i]);
		strcat(arg, "\n");
		fprintf(stderr, arg);
	}

	/* cipher_name is used as it's position is the first argument */
	if (strcmp(cipher_name, "-lc") == 0) {
		printAvailableCiphers();
		return 0;
	} else if (strcmp(cipher_name, "-ld") == 0) {
		printAvailableDigests();
		return 0;
	}

	/* Load the human readable error strings for libcrypto */
	ERR_load_crypto_strings();

	/* Load all digest and cipher algorithms */
	OpenSSL_add_all_algorithms();

	/* Load config file, and other important initialisation */
	OPENSSL_config(NULL);

	/*TODO: ... Do some crypto stuff here ... */

	const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipher_name);
	const EVP_MD *dgst = EVP_get_digestbyname(digest_name);
	unsigned char key[EVP_MAX_KEY_LENGTH];
	unsigned char iv[EVP_MAX_IV_LENGTH];
	const char* password = "******";
	const unsigned char *salt = NULL;

	if (!cipher) {
		fprintf(stderr,
				"Error loading %s algorithm, please use a different one.\n"
						"Use -lc to view a list of available ciphers.\n"
						"Example: %s -enc -lc\n", cipher_name, startup_path);
	} else {
		fprintf(stdout, "Successfully loaded %s algorithm.\n", cipher_name);
		maxKey = EVP_CIPHER_key_length(cipher) * 8;
		fprintf(stdout, "Using a %d bit key.\n", maxKey);
	}

	if (!dgst) {
		fprintf(stderr, "Couldn't load digest %s.\n"
				"Use -ld to view a list of available ciphers.\n"
				"Example: %s -enc -ld\n", digest_name, startup_path);
	} else {
		fprintf(stdout, "Successfully loaded %s digest.\n", digest_name);
	}

	if (!EVP_BytesToKey(cipher, dgst, salt, (unsigned char *) password,
			strlen(password), 1, key, iv)) {
		fprintf(stderr, "Key creation failed.\n");
		return 1;
	} else {
		//printf("Key: "); for(i=0; i<cipher->key_len; ++i) { printf("%02x", key[i]); } printf("\n");
		//printf("IV: "); for(i=0; i<cipher->iv_len; ++i) { printf("%02x", iv[i]); } printf("\n");
		fprintf(stdout,"Key succesfully generated\n");
	}

	if(enc_dir_recursive(rootDir)) {

	} else {
		fprintf(stderr,"Encryption failed.\n");
	}

	/* Clean up */

	/* Removes all digests and ciphers */
	EVP_cleanup();

	/* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */
	CRYPTO_cleanup_all_ex_data();

	/* Remove error strings */
	ERR_free_strings();

	return 0;
}
Exemple #27
0
int main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL;
    X509 *scert = NULL, *scert2 = NULL;
    EVP_PKEY *skey = NULL, *skey2 = NULL;
    PKCS7 *p7 = NULL;
    int ret = 1;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    tbio = BIO_new_file("signer.pem", "r");

    if (!tbio)
        goto err;

    scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    BIO_reset(tbio);

    skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

    BIO_free(tbio);

    tbio = BIO_new_file("signer2.pem", "r");

    if (!tbio)
        goto err;

    scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    BIO_reset(tbio);

    skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

    if (!scert2 || !skey2)
        goto err;

    in = BIO_new_file("sign.txt", "r");

    if (!in)
        goto err;

    p7 = PKCS7_sign(NULL, NULL, NULL, in, PKCS7_STREAM | PKCS7_PARTIAL);

    if (!p7)
        goto err;

    /* Add each signer in turn */

    if (!PKCS7_sign_add_signer(p7, scert, skey, NULL, 0))
        goto err;

    if (!PKCS7_sign_add_signer(p7, scert2, skey2, NULL, 0))
        goto err;

    out = BIO_new_file("smout.txt", "w");
    if (!out)
        goto err;

    /* NB: content included and finalized by SMIME_write_PKCS7 */

    if (!SMIME_write_PKCS7(out, p7, in, PKCS7_STREAM))
        goto err;

    ret = 0;

 err:
    if (ret) {
        fprintf(stderr, "Error Signing Data\n");
        ERR_print_errors_fp(stderr);
    }
    PKCS7_free(p7);
    X509_free(scert);
    EVP_PKEY_free(skey);
    X509_free(scert2);
    EVP_PKEY_free(skey2);
    BIO_free(in);
    BIO_free(out);
    BIO_free(tbio);
    return ret;
}
Exemple #28
0
int main(int argc, char **argv)
{
    BIO *sbio = NULL, *out = NULL;
    int i, len, rv;
    char tmpbuf[1024];
    SSL_CTX *ctx = NULL;
    SSL_CONF_CTX *cctx = NULL;
    SSL *ssl = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    const char *connect_str = "localhost:4433";
    long errline = -1;

    ERR_load_crypto_strings();
    ERR_load_SSL_strings();
    SSL_library_init();

    conf = NCONF_new(NULL);

    if (NCONF_load(conf, "connect.cnf", &errline) <= 0) {
        if (errline <= 0)
            fprintf(stderr, "Error processing config file\n");
        else
            fprintf(stderr, "Error on line %ld\n", errline);
        goto end;
    }

    sect = NCONF_get_section(conf, "default");

    if (sect == NULL) {
        fprintf(stderr, "Error retrieving default section\n");
        goto end;
    }

    ctx = SSL_CTX_new(SSLv23_client_method());
    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
    for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
        cnf = sk_CONF_VALUE_value(sect, i);
        rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value);
        if (rv > 0)
            continue;
        if (rv != -2) {
            fprintf(stderr, "Error processing %s = %s\n",
                    cnf->name, cnf->value);
            ERR_print_errors_fp(stderr);
            goto end;
        }
        if (!strcmp(cnf->name, "Connect")) {
            connect_str = cnf->value;
        } else {
            fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
            goto end;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }

    /*
     * We'd normally set some stuff like the verify paths and * mode here
     * because as things stand this will connect to * any server whose
     * certificate is signed by any CA.
     */

    sbio = BIO_new_ssl_connect(ctx);

    BIO_get_ssl(sbio, &ssl);

    if (!ssl) {
        fprintf(stderr, "Can't locate SSL pointer\n");
        goto end;
    }

    /* Don't want any retries */
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    /* We might want to do other things with ssl here */

    BIO_set_conn_hostname(sbio, connect_str);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);
    if (BIO_do_connect(sbio) <= 0) {
        fprintf(stderr, "Error connecting to server\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    if (BIO_do_handshake(sbio) <= 0) {
        fprintf(stderr, "Error establishing SSL connection\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    /* Could examine ssl here to get connection info */

    BIO_puts(sbio, "GET / HTTP/1.0\n\n");
    for (;;) {
        len = BIO_read(sbio, tmpbuf, 1024);
        if (len <= 0)
            break;
        BIO_write(out, tmpbuf, len);
    }
 end:
    SSL_CONF_CTX_free(cctx);
    BIO_free_all(sbio);
    BIO_free(out);
    NCONF_free(conf);
    return 0;
}
Exemple #29
0
int MAIN(int argc, char **argv)
	{
	int ret = 1;
	char *configfile = NULL;
	char *section = NULL;
	CONF *conf = NULL;
	enum mode {
	CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 
	} mode = CMD_NONE;
	char *data = NULL;
	char *digest = NULL;
	const EVP_MD *md = NULL;
	char *rnd = NULL;
	char *policy = NULL;
	int no_nonce = 0;
	int cert = 0;
	char *in = NULL;
	char *out = NULL;
	int text = 0;
	char *queryfile = NULL;
	char *passin = NULL;	/* Password source. */
	char *password =NULL;	/* Password itself. */
	char *inkey = NULL;
	char *signer = NULL;
	char *chain = NULL;
	char *ca_path = NULL;
	char *ca_file = NULL;
	char *untrusted = NULL;
	char *engine = NULL;
	/* Input is ContentInfo instead of TimeStampResp. */
	int token_in = 0;	
	/* Output is ContentInfo instead of TimeStampResp. */
	int token_out = 0;
	int free_bio_err = 0;

	ERR_load_crypto_strings();
	apps_startup();

	if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
		{
		free_bio_err = 1;
		BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
		}

	for (argc--, argv++; argc > 0; argc--, argv++)
		{
		if (strcmp(*argv, "-config") == 0)
			{
			if (argc-- < 1) goto usage;
			configfile = *++argv;
			}
		else if (strcmp(*argv, "-section") == 0)
			{
			if (argc-- < 1) goto usage;
			section = *++argv;
			}
		else if (strcmp(*argv, "-query") == 0)
			{
			if (mode != CMD_NONE) goto usage;
			mode = CMD_QUERY;
			}
		else if (strcmp(*argv, "-data") == 0)
			{
			if (argc-- < 1) goto usage;
			data = *++argv;
			}
		else if (strcmp(*argv, "-digest") == 0)
			{
			if (argc-- < 1) goto usage;
			digest = *++argv;
			}
		else if (strcmp(*argv, "-rand") == 0)
			{
			if (argc-- < 1) goto usage;
			rnd = *++argv;
			}
		else if (strcmp(*argv, "-policy") == 0)
			{
			if (argc-- < 1) goto usage;
			policy = *++argv;
			}
		else if (strcmp(*argv, "-no_nonce") == 0)
			{
			no_nonce = 1;
			}
		else if (strcmp(*argv, "-cert") == 0)
			{
			cert = 1;
			}
		else if (strcmp(*argv, "-in") == 0)
			{
			if (argc-- < 1) goto usage;
			in = *++argv;
			}
		else if (strcmp(*argv, "-token_in") == 0)
			{
			token_in = 1;
			}
		else if (strcmp(*argv, "-out") == 0)
			{
			if (argc-- < 1) goto usage;
			out = *++argv;
			}
		else if (strcmp(*argv, "-token_out") == 0)
			{
			token_out = 1;
			}
		else if (strcmp(*argv, "-text") == 0)
			{
			text = 1;
			}
		else if (strcmp(*argv, "-reply") == 0)
			{
			if (mode != CMD_NONE) goto usage;
			mode = CMD_REPLY;
			}
		else if (strcmp(*argv, "-queryfile") == 0)
			{
			if (argc-- < 1) goto usage;
			queryfile = *++argv;
			}
		else if (strcmp(*argv, "-passin") == 0)
			{
			if (argc-- < 1) goto usage;
			passin = *++argv;
			}
		else if (strcmp(*argv, "-inkey") == 0)
			{
			if (argc-- < 1) goto usage;
			inkey = *++argv;
			}
		else if (strcmp(*argv, "-signer") == 0)
			{
			if (argc-- < 1) goto usage;
			signer = *++argv;
			}
		else if (strcmp(*argv, "-chain") == 0)
			{
			if (argc-- < 1) goto usage;
			chain = *++argv;
			}
		else if (strcmp(*argv, "-verify") == 0)
			{
			if (mode != CMD_NONE) goto usage;
			mode = CMD_VERIFY;
			}
		else if (strcmp(*argv, "-CApath") == 0)
			{
			if (argc-- < 1) goto usage;
			ca_path = *++argv;
			}
		else if (strcmp(*argv, "-CAfile") == 0)
			{
			if (argc-- < 1) goto usage;
			ca_file = *++argv;
			}
		else if (strcmp(*argv, "-untrusted") == 0)
			{
			if (argc-- < 1) goto usage;
			untrusted = *++argv;
			}
		else if (strcmp(*argv, "-engine") == 0)
			{
			if (argc-- < 1) goto usage;
			engine = *++argv;
			}
		else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
			{
			/* empty. */
			}
		else
			goto usage;
		}
	
	/* Seed the random number generator if it is going to be used. */
	if (mode == CMD_QUERY && !no_nonce)
		{
		if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
			BIO_printf(bio_err, "warning, not much extra random "
				   "data, consider using the -rand option\n");
		if (rnd != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				   app_RAND_load_files(rnd));
		}

	/* Get the password if required. */
	if(mode == CMD_REPLY && passin &&
	   !app_passwd(bio_err, passin, NULL, &password, NULL))
		{
		BIO_printf(bio_err,"Error getting password.\n");
		goto cleanup;
		}

	/* Check consistency of parameters and execute 
	   the appropriate function. */
	switch (mode)
		{
	case CMD_NONE:
		goto usage;
	case CMD_QUERY:
		/* Data file and message imprint cannot be specified
		   at the same time. */
		ret = data != NULL && digest != NULL;
		if (ret) goto usage;
		/* Load the config file for possible policy OIDs. */
		conf = load_config_file(configfile);
		ret = !query_command(data, digest, md, policy, no_nonce, cert,
				     in, out, text);
		break;
	case CMD_REPLY:
		conf = load_config_file(configfile);
		if (in == NULL)
			{
			ret = !(queryfile != NULL && conf != NULL && !token_in);
			if (ret) goto usage;
			}
		else
			{
			/* 'in' and 'queryfile' are exclusive. */
			ret = !(queryfile == NULL);
			if (ret) goto usage;
			}

		ret = !reply_command(conf, section, engine, queryfile, 
				     password, inkey, signer, chain, policy, 
				     in, token_in, out, token_out, text);
		break;
	case CMD_VERIFY:
		ret = !(((queryfile && !data && !digest)
			 || (!queryfile && data && !digest)
			 || (!queryfile && !data && digest))
			&& in != NULL);
		if (ret) goto usage;

		ret = !verify_command(data, digest, queryfile, in, token_in,
				      ca_path, ca_file, untrusted);
		}

	goto cleanup;

 usage:
	BIO_printf(bio_err, "usage:\n"
		   "ts -query [-rand file%cfile%c...] [-config configfile] "
		   "[-data file_to_hash] [-digest digest_bytes]"
		   "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
		   "[-policy object_id] [-no_nonce] [-cert] "
		   "[-in request.tsq] [-out request.tsq] [-text]\n",
		   LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
	BIO_printf(bio_err, "or\n"
		   "ts -reply [-config configfile] [-section tsa_section] "
		   "[-queryfile request.tsq] [-passin password] "
		   "[-signer tsa_cert.pem] [-inkey private_key.pem] "
		   "[-chain certs_file.pem] [-policy object_id] "
		   "[-in response.tsr] [-token_in] "
		   "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
	BIO_printf(bio_err, "or\n"
		   "ts -verify [-data file_to_hash] [-digest digest_bytes] "
		   "[-queryfile request.tsq] "
		   "-in response.tsr [-token_in] "
		   "-CApath ca_path -CAfile ca_file.pem "
		   "-untrusted cert_file.pem\n");
 cleanup:
	/* Clean up. */
	app_RAND_write_file(NULL, bio_err);
	NCONF_free(conf);
	OPENSSL_free(password);
	OBJ_cleanup();
	if (free_bio_err)
		{
		BIO_free_all(bio_err);
		bio_err = NULL;
		}

	OPENSSL_EXIT(ret);
	}
SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const string &certchainfile):
    pCtx (NULL),
    PrivateKey (NULL),
    Certificate (NULL)
{
    /* TODO: the usage of the specified private-key and cert-chain filenames only applies to
     * client-side connections at this point. Server connections currently use the default materials.
     * That needs to be fixed asap.
     * Also, in this implementation, server-side connections use statically defined X-509 defaults.
     * One thing I'm really not clear on is whether or not you have to explicitly free X509 and EVP_PKEY
     * objects when we call our destructor, or whether just calling SSL_CTX_free is enough.
     */

    if (!bLibraryInitialized) {
        bLibraryInitialized = true;
        SSL_library_init();
        OpenSSL_add_ssl_algorithms();
        OpenSSL_add_all_algorithms();
        SSL_load_error_strings();
        ERR_load_crypto_strings();

        InitializeDefaultCredentials();
    }

    bIsServer = is_server;
    pCtx = SSL_CTX_new (is_server ? SSLv23_server_method() : SSLv23_client_method());
    if (!pCtx)
        throw std::runtime_error ("no SSL context");

    SSL_CTX_set_options (pCtx, SSL_OP_ALL);
    //SSL_CTX_set_options (pCtx, (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3));

    if (is_server) {
        // The SSL_CTX calls here do NOT allocate memory.
        int e;
        if (privkeyfile.length() > 0)
            e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
        else
            e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey);
        assert (e > 0);
        if (certchainfile.length() > 0)
            e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
        else
            e = SSL_CTX_use_certificate (pCtx, DefaultCertificate);
        assert (e > 0);
    }

    SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH");

    if (is_server) {
        SSL_CTX_sess_set_cache_size (pCtx, 128);
        SSL_CTX_set_session_id_context (pCtx, (unsigned char*)"eventmachine", 12);
    }
    else {
        int e;
        if (privkeyfile.length() > 0) {
            e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
            assert (e > 0);
        }
        if (certchainfile.length() > 0) {
            e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
            assert (e > 0);
        }
    }
}