Example #1
0
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
	{
	char buf[80], *p = buf;
	int i;

	if ((a == NULL) || (a->data == NULL))
		return(BIO_write(bp,"NULL",4));
	i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
	if (i > (int)(sizeof(buf) - 1))
		{
		p = OPENSSL_malloc(i + 1);
		if (!p)
			return -1;
		i2t_ASN1_OBJECT(p,i + 1,a);
		}
	if (i <= 0)
		 {
		 i = BIO_write(bp, "<INVALID>", 9);
		 i += BIO_dump(bp, (const char *)a->data, a->length);
		 return i;
		 }
	BIO_write(bp,p,i);
	if (p != buf)
		OPENSSL_free(p);
	return(i);
	}
Example #2
0
void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
					unsigned char *data, int len,
					void *arg)
	{
	BIO *bio = arg;
	char *extname;

	switch(type)
		{
		case TLSEXT_TYPE_server_name:
		extname = "server name";
		break;

		case TLSEXT_TYPE_max_fragment_length:
		extname = "max fragment length";
		break;

		case TLSEXT_TYPE_client_certificate_url:
		extname = "client certificate URL";
		break;

		case TLSEXT_TYPE_trusted_ca_keys:
		extname = "trusted CA keys";
		break;

		case TLSEXT_TYPE_truncated_hmac:
		extname = "truncated HMAC";
		break;

		case TLSEXT_TYPE_status_request:
		extname = "status request";
		break;

		case TLSEXT_TYPE_elliptic_curves:
		extname = "elliptic curves";
		break;

		case TLSEXT_TYPE_ec_point_formats:
		extname = "EC point formats";
		break;

		case TLSEXT_TYPE_session_ticket:
		extname = "server ticket";
		break;


		default:
		extname = "unknown";
		break;

		}
	
	BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
			client_server ? "server": "client",
			extname, type, len);
	BIO_dump(bio, (char *)data, len);
	(void)BIO_flush(bio);
	}
Example #3
0
/* Debug callback tracks raw SSL buffers.  Initialized by 
 * BIO_set_callback().  Invoked when debug level is >= 4.
 */
long bio_dump_cb(BIO *bio, int cmd, char *argp,
                        int argi, long argl, long ret) {
  BIO *out;
  out=(BIO *)BIO_get_callback_arg(bio);
  if (out == NULL) return(ret);
  if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) {
    BIO_printf(out,"read from %08X [%08lX] (%d bytes => %ld (0x%X))\n",
               bio,argp,argi,ret,ret);
    BIO_dump(out,argp,(int)ret);
    return(ret);
  }
  else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) {
    BIO_printf(out,"write to %08X [%08lX] (%d bytes => %ld (0x%X))\n",
               bio,argp,argi,ret,ret);
    BIO_dump(out,argp,(int)ret);
  }
  return(ret);
}
Example #4
0
long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
				   int argi, long argl, long ret)
	{
	BIO *out;

	out=(BIO *)BIO_get_callback_arg(bio);
	if (out == NULL) return(ret);

	if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
		{
		BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
 			(void *)bio,argp,(unsigned long)argi,ret,ret);
		BIO_dump(out,argp,(int)ret);
		return(ret);
		}
	else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
		{
		BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
			(void *)bio,argp,(unsigned long)argi,ret,ret);
		BIO_dump(out,argp,(int)ret);
		}
	return(ret);
	}
Example #5
0
int
pkeyutl_main(int argc, char **argv)
{
	BIO *in = NULL, *out = NULL;
	char *infile = NULL, *outfile = NULL, *sigfile = NULL;
	int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
	int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
	char badarg = 0, rev = 0;
	char hexdump = 0, asn1parse = 0;
	EVP_PKEY_CTX *ctx = NULL;
	char *passargin = NULL;
	int keysize = -1;

	unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
	size_t buf_outlen = 0;
	int buf_inlen = 0, siglen = -1;

	int ret = 1, rv = -1;

	if (single_execution) {
		if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	argc--;
	argv++;

	while (argc >= 1) {
		if (!strcmp(*argv, "-in")) {
			if (--argc < 1)
				badarg = 1;
			else
				infile = *(++argv);
		} else if (!strcmp(*argv, "-out")) {
			if (--argc < 1)
				badarg = 1;
			else
				outfile = *(++argv);
		} else if (!strcmp(*argv, "-sigfile")) {
			if (--argc < 1)
				badarg = 1;
			else
				sigfile = *(++argv);
		} else if (!strcmp(*argv, "-inkey")) {
			if (--argc < 1)
				badarg = 1;
			else {
				ctx = init_ctx(&keysize,
				    *(++argv), keyform, key_type,
				    passargin, pkey_op);
				if (!ctx) {
					BIO_puts(bio_err,
					    "Error initializing context\n");
					ERR_print_errors(bio_err);
					badarg = 1;
				}
			}
		} else if (!strcmp(*argv, "-peerkey")) {
			if (--argc < 1)
				badarg = 1;
			else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
				badarg = 1;
		} else if (!strcmp(*argv, "-passin")) {
			if (--argc < 1)
				badarg = 1;
			else
				passargin = *(++argv);
		} else if (strcmp(*argv, "-peerform") == 0) {
			if (--argc < 1)
				badarg = 1;
			else
				peerform = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-keyform") == 0) {
			if (--argc < 1)
				badarg = 1;
			else
				keyform = str2fmt(*(++argv));
		}
		else if (!strcmp(*argv, "-pubin"))
			key_type = KEY_PUBKEY;
		else if (!strcmp(*argv, "-certin"))
			key_type = KEY_CERT;
		else if (!strcmp(*argv, "-asn1parse"))
			asn1parse = 1;
		else if (!strcmp(*argv, "-hexdump"))
			hexdump = 1;
		else if (!strcmp(*argv, "-sign"))
			pkey_op = EVP_PKEY_OP_SIGN;
		else if (!strcmp(*argv, "-verify"))
			pkey_op = EVP_PKEY_OP_VERIFY;
		else if (!strcmp(*argv, "-verifyrecover"))
			pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
		else if (!strcmp(*argv, "-rev"))
			rev = 1;
		else if (!strcmp(*argv, "-encrypt"))
			pkey_op = EVP_PKEY_OP_ENCRYPT;
		else if (!strcmp(*argv, "-decrypt"))
			pkey_op = EVP_PKEY_OP_DECRYPT;
		else if (!strcmp(*argv, "-derive"))
			pkey_op = EVP_PKEY_OP_DERIVE;
		else if (strcmp(*argv, "-pkeyopt") == 0) {
			if (--argc < 1)
				badarg = 1;
			else if (!ctx) {
				BIO_puts(bio_err,
				    "-pkeyopt command before -inkey\n");
				badarg = 1;
			} else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) {
				BIO_puts(bio_err, "parameter setting error\n");
				ERR_print_errors(bio_err);
				goto end;
			}
		} else
			badarg = 1;
		if (badarg) {
			usage();
			goto end;
		}
		argc--;
		argv++;
	}

	if (!ctx) {
		usage();
		goto end;
	}
	if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) {
		BIO_puts(bio_err, "Signature file specified for non verify\n");
		goto end;
	}
	if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) {
		BIO_puts(bio_err, "No signature file specified for verify\n");
		goto end;
	}

	if (pkey_op != EVP_PKEY_OP_DERIVE) {
		if (infile) {
			if (!(in = BIO_new_file(infile, "rb"))) {
				BIO_puts(bio_err,
				    "Error Opening Input File\n");
				ERR_print_errors(bio_err);
				goto end;
			}
		} else
			in = BIO_new_fp(stdin, BIO_NOCLOSE);
	}
	if (outfile) {
		if (!(out = BIO_new_file(outfile, "wb"))) {
			BIO_printf(bio_err, "Error Creating Output File\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	}

	if (sigfile) {
		BIO *sigbio = BIO_new_file(sigfile, "rb");
		if (!sigbio) {
			BIO_printf(bio_err, "Can't open signature file %s\n",
			    sigfile);
			goto end;
		}
		siglen = bio_to_mem(&sig, keysize * 10, sigbio);
		BIO_free(sigbio);
		if (siglen <= 0) {
			BIO_printf(bio_err, "Error reading signature data\n");
			goto end;
		}
	}
	if (in) {
		/* Read the input data */
		buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
		if (buf_inlen <= 0) {
			BIO_printf(bio_err, "Error reading input Data\n");
			exit(1);
		}
		if (rev) {
			size_t i;
			unsigned char ctmp;
			size_t l = (size_t) buf_inlen;
			for (i = 0; i < l / 2; i++) {
				ctmp = buf_in[i];
				buf_in[i] = buf_in[l - 1 - i];
				buf_in[l - 1 - i] = ctmp;
			}
		}
	}
	if (pkey_op == EVP_PKEY_OP_VERIFY) {
		rv = EVP_PKEY_verify(ctx, sig, (size_t) siglen,
		    buf_in, (size_t) buf_inlen);
		if (rv == 1) {
			BIO_puts(out, "Signature Verified Successfully\n");
			ret = 0;
		} else
			BIO_puts(out, "Signature Verification Failure\n");
		if (rv >= 0)
			goto end;
	} else {
		rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
		    buf_in, (size_t) buf_inlen);
		if (rv > 0) {
			buf_out = malloc(buf_outlen);
			if (!buf_out)
				rv = -1;
			else
				rv = do_keyop(ctx, pkey_op,
				    buf_out, (size_t *) & buf_outlen,
				    buf_in, (size_t) buf_inlen);
		}
	}

	if (rv <= 0) {
		BIO_printf(bio_err, "Public Key operation error\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	ret = 0;
	if (asn1parse) {
		if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
			ERR_print_errors(bio_err);
	} else if (hexdump)
		BIO_dump(out, (char *) buf_out, buf_outlen);
	else
		BIO_write(out, buf_out, buf_outlen);

 end:
	EVP_PKEY_CTX_free(ctx);
	BIO_free(in);
	BIO_free_all(out);
	free(buf_in);
	free(buf_out);
	free(sig);

	return ret;
}
Example #6
0
void
tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len,
    void *arg)
{
	BIO *bio = arg;
	char *extname;

	switch (type) {
	case TLSEXT_TYPE_server_name:
		extname = "server name";
		break;

	case TLSEXT_TYPE_max_fragment_length:
		extname = "max fragment length";
		break;

	case TLSEXT_TYPE_client_certificate_url:
		extname = "client certificate URL";
		break;

	case TLSEXT_TYPE_trusted_ca_keys:
		extname = "trusted CA keys";
		break;

	case TLSEXT_TYPE_truncated_hmac:
		extname = "truncated HMAC";
		break;

	case TLSEXT_TYPE_status_request:
		extname = "status request";
		break;

	case TLSEXT_TYPE_user_mapping:
		extname = "user mapping";
		break;

	case TLSEXT_TYPE_client_authz:
		extname = "client authz";
		break;

	case TLSEXT_TYPE_server_authz:
		extname = "server authz";
		break;

	case TLSEXT_TYPE_cert_type:
		extname = "cert type";
		break;

	case TLSEXT_TYPE_elliptic_curves:
		extname = "elliptic curves";
		break;

	case TLSEXT_TYPE_ec_point_formats:
		extname = "EC point formats";
		break;

	case TLSEXT_TYPE_srp:
		extname = "SRP";
		break;

	case TLSEXT_TYPE_signature_algorithms:
		extname = "signature algorithms";
		break;

	case TLSEXT_TYPE_use_srtp:
		extname = "use SRTP";
		break;

	case TLSEXT_TYPE_heartbeat:
		extname = "heartbeat";
		break;

	case TLSEXT_TYPE_session_ticket:
		extname = "session ticket";
		break;

	case TLSEXT_TYPE_renegotiate:
		extname = "renegotiation info";
		break;

	case TLSEXT_TYPE_application_layer_protocol_negotiation:
		extname = "application layer protocol negotiation";
		break;

	case TLSEXT_TYPE_padding:
		extname = "TLS padding";
		break;

	default:
		extname = "unknown";
		break;

	}

	BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
	    client_server ? "server" : "client", extname, type, len);
	BIO_dump(bio, (char *) data, len);
	(void) BIO_flush(bio);
}
Example #7
0
int pkeyutl_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    ENGINE *e = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL;
    char hexdump = 0, asn1parse = 0, rev = 0, *prog;
    unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
    OPTION_CHOICE o;
    int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform =
        FORMAT_PEM;
    int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
    int engine_impl = 0;
    int ret = 1, rv = -1;
    size_t buf_outlen;
    const char *inkey = NULL;
    const char *peerkey = NULL;
    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;

    prog = opt_init(argc, argv, pkeyutl_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(pkeyutl_options);
            ret = 0;
            goto end;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGFILE:
            sigfile = opt_arg();
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_INKEY:
            inkey = opt_arg();
            break;
        case OPT_PEERKEY:
            peerkey = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PEERFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_PUBIN:
            key_type = KEY_PUBKEY;
            break;
        case OPT_CERTIN:
            key_type = KEY_CERT;
            break;
        case OPT_ASN1PARSE:
            asn1parse = 1;
            break;
        case OPT_HEXDUMP:
            hexdump = 1;
            break;
        case OPT_SIGN:
            pkey_op = EVP_PKEY_OP_SIGN;
            break;
        case OPT_VERIFY:
            pkey_op = EVP_PKEY_OP_VERIFY;
            break;
        case OPT_VERIFYRECOVER:
            pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
            break;
        case OPT_ENCRYPT:
            pkey_op = EVP_PKEY_OP_ENCRYPT;
            break;
        case OPT_DECRYPT:
            pkey_op = EVP_PKEY_OP_DECRYPT;
            break;
        case OPT_DERIVE:
            pkey_op = EVP_PKEY_OP_DERIVE;
            break;
        case OPT_REV:
            rev = 1;
            break;
        case OPT_PKEYOPT:
            if ((pkeyopts == NULL &&
                 (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) ||
                sk_OPENSSL_STRING_push(pkeyopts, *++argv) == 0) {
                BIO_puts(bio_err, "out of memory\n");
                goto end;
            }
            break;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    if (inkey == NULL ||
        (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE))
        goto opthelp;

    ctx = init_ctx(&keysize, inkey, keyform, key_type,
                   passinarg, pkey_op, e, engine_impl);
    if (ctx == NULL) {
        BIO_printf(bio_err, "%s: Error initializing context\n", prog);
        ERR_print_errors(bio_err);
        goto end;
    }
    if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) {
        BIO_printf(bio_err, "%s: Error setting up peer key\n", prog);
        ERR_print_errors(bio_err);
        goto end;
    }
    if (pkeyopts != NULL) {
        int num = sk_OPENSSL_STRING_num(pkeyopts);
        int i;

        for (i = 0; i < num; ++i) {
            const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i);

            if (pkey_ctrl_string(ctx, opt) <= 0) {
                BIO_printf(bio_err, "%s: Can't set parameter:\n", prog);
                ERR_print_errors(bio_err);
                goto end;
            }
        }
    }

    if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) {
        BIO_printf(bio_err,
                   "%s: Signature file specified for non verify\n", prog);
        goto end;
    }

    if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) {
        BIO_printf(bio_err,
                   "%s: No signature file specified for verify\n", prog);
        goto end;
    }

/* FIXME: seed PRNG only if needed */
    app_RAND_load_file(NULL, 0);

    if (pkey_op != EVP_PKEY_OP_DERIVE) {
        in = bio_open_default(infile, 'r', FORMAT_BINARY);
        if (in == NULL)
            goto end;
    }
    out = bio_open_default(outfile, 'w', FORMAT_BINARY);
    if (out == NULL)
        goto end;

    if (sigfile) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Can't open signature file %s\n", sigfile);
            goto end;
        }
        siglen = bio_to_mem(&sig, keysize * 10, sigbio);
        BIO_free(sigbio);
        if (siglen < 0) {
            BIO_printf(bio_err, "Error reading signature data\n");
            goto end;
        }
    }

    if (in) {
        /* Read the input data */
        buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
        if (buf_inlen < 0) {
            BIO_printf(bio_err, "Error reading input Data\n");
            exit(1);
        }
        if (rev) {
            size_t i;
            unsigned char ctmp;
            size_t l = (size_t)buf_inlen;
            for (i = 0; i < l / 2; i++) {
                ctmp = buf_in[i];
                buf_in[i] = buf_in[l - 1 - i];
                buf_in[l - 1 - i] = ctmp;
            }
        }
    }

    if (pkey_op == EVP_PKEY_OP_VERIFY) {
        rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
                             buf_in, (size_t)buf_inlen);
        if (rv == 1) {
            BIO_puts(out, "Signature Verified Successfully\n");
            ret = 0;
        } else
            BIO_puts(out, "Signature Verification Failure\n");
        goto end;
    }
    rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
                  buf_in, (size_t)buf_inlen);
    if (rv > 0 && buf_outlen != 0) {
        buf_out = app_malloc(buf_outlen, "buffer output");
        rv = do_keyop(ctx, pkey_op,
                      buf_out, (size_t *)&buf_outlen,
                      buf_in, (size_t)buf_inlen);
    }
    if (rv < 0) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;

    if (asn1parse) {
        if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
            ERR_print_errors(bio_err);
    } else if (hexdump)
        BIO_dump(out, (char *)buf_out, buf_outlen);
    else
        BIO_write(out, buf_out, buf_outlen);

 end:
    EVP_PKEY_CTX_free(ctx);
    BIO_free(in);
    BIO_free_all(out);
    OPENSSL_free(buf_in);
    OPENSSL_free(buf_out);
    OPENSSL_free(sig);
    sk_OPENSSL_STRING_free(pkeyopts);
    return ret;
}
Example #8
0
int rsautl_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    ENGINE *e = NULL;
    EVP_PKEY *pkey = NULL;
    RSA *rsa = NULL;
    X509 *x;
    char *infile = NULL, *outfile = NULL, *keyfile = NULL;
    char *passinarg = NULL, *passin = NULL, *prog;
    char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
    unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING;
    int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1;
    int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, rsautl_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(rsautl_options);
            ret = 0;
            goto end;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_ASN1PARSE:
            asn1parse = 1;
            break;
        case OPT_HEXDUMP:
            hexdump = 1;
            break;
        case OPT_RAW:
            pad = RSA_NO_PADDING;
            break;
        case OPT_OAEP:
            pad = RSA_PKCS1_OAEP_PADDING;
            break;
        case OPT_SSL:
            pad = RSA_SSLV23_PADDING;
            break;
        case OPT_PKCS:
            pad = RSA_PKCS1_PADDING;
            break;
        case OPT_X931:
            pad = RSA_X931_PADDING;
            break;
        case OPT_SIGN:
            rsa_mode = RSA_SIGN;
            need_priv = 1;
            break;
        case OPT_VERIFY:
            rsa_mode = RSA_VERIFY;
            break;
        case OPT_REV:
            rev = 1;
            break;
        case OPT_ENCRYPT:
            rsa_mode = RSA_ENCRYPT;
            break;
        case OPT_DECRYPT:
            rsa_mode = RSA_DECRYPT;
            need_priv = 1;
            break;
        case OPT_PUBIN:
            key_type = KEY_PUBKEY;
            break;
        case OPT_CERTIN:
            key_type = KEY_CERT;
            break;
        case OPT_INKEY:
            keyfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (need_priv && (key_type != KEY_PRIVKEY)) {
        BIO_printf(bio_err, "A private key is needed for this operation\n");
        goto end;
    }

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (!app_load_modules(NULL))
        goto end;

/* FIXME: seed PRNG only if needed */
    app_RAND_load_file(NULL, 0);

    switch (key_type) {
    case KEY_PRIVKEY:
        pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key");
        break;

    case KEY_PUBKEY:
        pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key");
        break;

    case KEY_CERT:
        x = load_cert(keyfile, keyformat, NULL, e, "Certificate");
        if (x) {
            pkey = X509_get_pubkey(x);
            X509_free(x);
        }
        break;
    }

    if (!pkey) {
        return 1;
    }

    rsa = EVP_PKEY_get1_RSA(pkey);
    EVP_PKEY_free(pkey);

    if (!rsa) {
        BIO_printf(bio_err, "Error getting RSA key\n");
        ERR_print_errors(bio_err);
        goto end;
    }

    in = bio_open_default(infile, 'r', FORMAT_BINARY);
    if (in == NULL)
        goto end;
    out = bio_open_default(outfile, 'w', FORMAT_BINARY);
    if (out == NULL)
        goto end;

    keysize = RSA_size(rsa);

    rsa_in = app_malloc(keysize * 2, "hold rsa key");
    rsa_out = app_malloc(keysize, "output rsa key");

    /* Read the input data */
    rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
    if (rsa_inlen <= 0) {
        BIO_printf(bio_err, "Error reading input Data\n");
        goto end;
    }
    if (rev) {
        int i;
        unsigned char ctmp;
        for (i = 0; i < rsa_inlen / 2; i++) {
            ctmp = rsa_in[i];
            rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
            rsa_in[rsa_inlen - 1 - i] = ctmp;
        }
    }
    switch (rsa_mode) {

    case RSA_VERIFY:
        rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
        break;

    case RSA_SIGN:
        rsa_outlen =
            RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
        break;

    case RSA_ENCRYPT:
        rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
        break;

    case RSA_DECRYPT:
        rsa_outlen =
            RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
        break;

    }

    if (rsa_outlen <= 0) {
        BIO_printf(bio_err, "RSA operation error\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
    if (asn1parse) {
        if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
            ERR_print_errors(bio_err);
        }
    } else if (hexdump)
        BIO_dump(out, (char *)rsa_out, rsa_outlen);
    else
        BIO_write(out, rsa_out, rsa_outlen);
 end:
    RSA_free(rsa);
    BIO_free(in);
    BIO_free_all(out);
    OPENSSL_free(rsa_in);
    OPENSSL_free(rsa_out);
    OPENSSL_free(passin);
    return ret;
}
Example #9
0
int
rsautl_main(int argc, char **argv)
{
	ENGINE *e = NULL;
	BIO *in = NULL, *out = NULL;
	char *infile = NULL, *outfile = NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	char *keyfile = NULL;
	char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
	int keyform = FORMAT_PEM;
	char need_priv = 0, badarg = 0, rev = 0;
	char hexdump = 0, asn1parse = 0;
	X509 *x;
	EVP_PKEY *pkey = NULL;
	RSA *rsa = NULL;
	unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
	char *passargin = NULL, *passin = NULL;
	int rsa_inlen, rsa_outlen = 0;
	int keysize;

	int ret = 1;

	argc--;
	argv++;

	pad = RSA_PKCS1_PADDING;

	while (argc >= 1) {
		if (!strcmp(*argv, "-in")) {
			if (--argc < 1)
				badarg = 1;
			else
				infile = *(++argv);
		} else if (!strcmp(*argv, "-out")) {
			if (--argc < 1)
				badarg = 1;
			else
				outfile = *(++argv);
		} else if (!strcmp(*argv, "-inkey")) {
			if (--argc < 1)
				badarg = 1;
			else
				keyfile = *(++argv);
		} else if (!strcmp(*argv, "-passin")) {
			if (--argc < 1)
				badarg = 1;
			else
				passargin = *(++argv);
		} else if (strcmp(*argv, "-keyform") == 0) {
			if (--argc < 1)
				badarg = 1;
			else
				keyform = str2fmt(*(++argv));
#ifndef OPENSSL_NO_ENGINE
		} else if (!strcmp(*argv, "-engine")) {
			if (--argc < 1)
				badarg = 1;
			else
				engine = *(++argv);
#endif
		} else if (!strcmp(*argv, "-pubin")) {
			key_type = KEY_PUBKEY;
		} else if (!strcmp(*argv, "-certin")) {
			key_type = KEY_CERT;
		} else if (!strcmp(*argv, "-asn1parse"))
			asn1parse = 1;
		else if (!strcmp(*argv, "-hexdump"))
			hexdump = 1;
		else if (!strcmp(*argv, "-raw"))
			pad = RSA_NO_PADDING;
		else if (!strcmp(*argv, "-oaep"))
			pad = RSA_PKCS1_OAEP_PADDING;
		else if (!strcmp(*argv, "-ssl"))
			pad = RSA_SSLV23_PADDING;
		else if (!strcmp(*argv, "-pkcs"))
			pad = RSA_PKCS1_PADDING;
		else if (!strcmp(*argv, "-x931"))
			pad = RSA_X931_PADDING;
		else if (!strcmp(*argv, "-sign")) {
			rsa_mode = RSA_SIGN;
			need_priv = 1;
		} else if (!strcmp(*argv, "-verify"))
			rsa_mode = RSA_VERIFY;
		else if (!strcmp(*argv, "-rev"))
			rev = 1;
		else if (!strcmp(*argv, "-encrypt"))
			rsa_mode = RSA_ENCRYPT;
		else if (!strcmp(*argv, "-decrypt")) {
			rsa_mode = RSA_DECRYPT;
			need_priv = 1;
		} else
			badarg = 1;
		if (badarg) {
			usage();
			goto end;
		}
		argc--;
		argv++;
	}

	if (need_priv && (key_type != KEY_PRIVKEY)) {
		BIO_printf(bio_err, "A private key is needed for this operation\n");
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	e = setup_engine(bio_err, engine, 0);
#endif
	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}

	switch (key_type) {
	case KEY_PRIVKEY:
		pkey = load_key(bio_err, keyfile, keyform, 0,
		    passin, e, "Private Key");
		break;

	case KEY_PUBKEY:
		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
		    NULL, e, "Public Key");
		break;

	case KEY_CERT:
		x = load_cert(bio_err, keyfile, keyform,
		    NULL, e, "Certificate");
		if (x) {
			pkey = X509_get_pubkey(x);
			X509_free(x);
		}
		break;
	}

	if (!pkey) {
		return 1;
	}
	rsa = EVP_PKEY_get1_RSA(pkey);
	EVP_PKEY_free(pkey);

	if (!rsa) {
		BIO_printf(bio_err, "Error getting RSA key\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile) {
		if (!(in = BIO_new_file(infile, "rb"))) {
			BIO_printf(bio_err, "Error Reading Input File\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	} else
		in = BIO_new_fp(stdin, BIO_NOCLOSE);

	if (outfile) {
		if (!(out = BIO_new_file(outfile, "wb"))) {
			BIO_printf(bio_err, "Error Reading Output File\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	}

	keysize = RSA_size(rsa);

	rsa_in = reallocarray(NULL, keysize, 2);
	rsa_out = malloc(keysize);

	/* Read the input data */
	rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
	if (rsa_inlen <= 0) {
		BIO_printf(bio_err, "Error reading input Data\n");
		exit(1);
	}
	if (rev) {
		int i;
		unsigned char ctmp;
		for (i = 0; i < rsa_inlen / 2; i++) {
			ctmp = rsa_in[i];
			rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
			rsa_in[rsa_inlen - 1 - i] = ctmp;
		}
	}
	switch (rsa_mode) {

	case RSA_VERIFY:
		rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	case RSA_SIGN:
		rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	case RSA_ENCRYPT:
		rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	case RSA_DECRYPT:
		rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	}

	if (rsa_outlen <= 0) {
		BIO_printf(bio_err, "RSA operation error\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	ret = 0;
	if (asn1parse) {
		if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
			ERR_print_errors(bio_err);
		}
	} else if (hexdump)
		BIO_dump(out, (char *) rsa_out, rsa_outlen);
	else
		BIO_write(out, rsa_out, rsa_outlen);

end:
	RSA_free(rsa);
	BIO_free(in);
	BIO_free_all(out);
	free(rsa_in);
	free(rsa_out);
	free(passin);

	return ret;
}
Example #10
0
int pkeyutl_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    ENGINE *e = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey = NULL;
    char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL;
    char hexdump = 0, asn1parse = 0, rev = 0, *prog;
    unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
    OPTION_CHOICE o;
    int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform = FORMAT_PEM;
    int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
    int engine_impl = 0;
    int ret = 1, rv = -1;
    size_t buf_outlen;
    const char *inkey = NULL;
    const char *peerkey = NULL;
    const char *kdfalg = NULL;
    int kdflen = 0;
    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;
    STACK_OF(OPENSSL_STRING) *pkeyopts_passin = NULL;
    int rawin = 0;
    const EVP_MD *md = NULL;

    prog = opt_init(argc, argv, pkeyutl_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(pkeyutl_options);
            ret = 0;
            goto end;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGFILE:
            sigfile = opt_arg();
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_INKEY:
            inkey = opt_arg();
            break;
        case OPT_PEERKEY:
            peerkey = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PEERFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
                goto opthelp;
            break;
        case OPT_R_CASES:
            if (!opt_rand(o))
                goto end;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_PUBIN:
            key_type = KEY_PUBKEY;
            break;
        case OPT_CERTIN:
            key_type = KEY_CERT;
            break;
        case OPT_ASN1PARSE:
            asn1parse = 1;
            break;
        case OPT_HEXDUMP:
            hexdump = 1;
            break;
        case OPT_SIGN:
            pkey_op = EVP_PKEY_OP_SIGN;
            break;
        case OPT_VERIFY:
            pkey_op = EVP_PKEY_OP_VERIFY;
            break;
        case OPT_VERIFYRECOVER:
            pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
            break;
        case OPT_ENCRYPT:
            pkey_op = EVP_PKEY_OP_ENCRYPT;
            break;
        case OPT_DECRYPT:
            pkey_op = EVP_PKEY_OP_DECRYPT;
            break;
        case OPT_DERIVE:
            pkey_op = EVP_PKEY_OP_DERIVE;
            break;
        case OPT_KDF:
            pkey_op = EVP_PKEY_OP_DERIVE;
            key_type = KEY_NONE;
            kdfalg = opt_arg();
            break;
        case OPT_KDFLEN:
            kdflen = atoi(opt_arg());
            break;
        case OPT_REV:
            rev = 1;
            break;
        case OPT_PKEYOPT:
            if ((pkeyopts == NULL &&
                 (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) ||
                sk_OPENSSL_STRING_push(pkeyopts, opt_arg()) == 0) {
                BIO_puts(bio_err, "out of memory\n");
                goto end;
            }
            break;
        case OPT_PKEYOPT_PASSIN:
            if ((pkeyopts_passin == NULL &&
                 (pkeyopts_passin = sk_OPENSSL_STRING_new_null()) == NULL) ||
                sk_OPENSSL_STRING_push(pkeyopts_passin, opt_arg()) == 0) {
                BIO_puts(bio_err, "out of memory\n");
                goto end;
            }
            break;
        case OPT_RAWIN:
            rawin = 1;
            break;
        case OPT_DIGEST:
            if (!opt_md(opt_arg(), &md))
                goto end;
            break;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    if (rawin && pkey_op != EVP_PKEY_OP_SIGN && pkey_op != EVP_PKEY_OP_VERIFY) {
        BIO_printf(bio_err,
                   "%s: -rawin can only be used with -sign or -verify\n",
                   prog);
        goto opthelp;
    }

    if (md != NULL && !rawin) {
        BIO_printf(bio_err,
                   "%s: -digest can only be used with -rawin\n",
                   prog);
        goto opthelp;
    }

    if (rawin && rev) {
        BIO_printf(bio_err, "%s: -rev cannot be used with raw input\n",
                   prog);
        goto opthelp;
    }

    if (kdfalg != NULL) {
        if (kdflen == 0) {
            BIO_printf(bio_err,
                       "%s: no KDF length given (-kdflen parameter).\n", prog);
            goto opthelp;
        }
    } else if (inkey == NULL) {
        BIO_printf(bio_err,
                   "%s: no private key given (-inkey parameter).\n", prog);
        goto opthelp;
    } else if (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE) {
        BIO_printf(bio_err,
                   "%s: no peer key given (-peerkey parameter).\n", prog);
        goto opthelp;
    }
    ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
                   passinarg, pkey_op, e, engine_impl, &pkey);
    if (ctx == NULL) {
        BIO_printf(bio_err, "%s: Error initializing context\n", prog);
        ERR_print_errors(bio_err);
        goto end;
    }
    if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) {
        BIO_printf(bio_err, "%s: Error setting up peer key\n", prog);
        ERR_print_errors(bio_err);
        goto end;
    }
    if (pkeyopts != NULL) {
        int num = sk_OPENSSL_STRING_num(pkeyopts);
        int i;

        for (i = 0; i < num; ++i) {
            const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i);

            if (pkey_ctrl_string(ctx, opt) <= 0) {
                BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",
                           prog, opt);
                ERR_print_errors(bio_err);
                goto end;
            }
        }
    }
    if (pkeyopts_passin != NULL) {
        int num = sk_OPENSSL_STRING_num(pkeyopts_passin);
        int i;

        for (i = 0; i < num; i++) {
            char *opt = sk_OPENSSL_STRING_value(pkeyopts_passin, i);
            char *passin = strchr(opt, ':');
            char *passwd;

            if (passin == NULL) {
                /* Get password interactively */
                char passwd_buf[4096];
                BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt);
                EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1,
                                   passwd_buf, 0);
                passwd = OPENSSL_strdup(passwd_buf);
                if (passwd == NULL) {
                    BIO_puts(bio_err, "out of memory\n");
                    goto end;
                }
            } else {
                /* Get password as a passin argument: First split option name
                 * and passphrase argument into two strings */
                *passin = 0;
                passin++;
                if (app_passwd(passin, NULL, &passwd, NULL) == 0) {
                    BIO_printf(bio_err, "failed to get '%s'\n", opt);
                    goto end;
                }
            }

            if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) {
                BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",
                           prog, opt);
                goto end;
            }
            OPENSSL_free(passwd);
        }
    }

    if (sigfile != NULL && (pkey_op != EVP_PKEY_OP_VERIFY)) {
        BIO_printf(bio_err,
                   "%s: Signature file specified for non verify\n", prog);
        goto end;
    }

    if (sigfile == NULL && (pkey_op == EVP_PKEY_OP_VERIFY)) {
        BIO_printf(bio_err,
                   "%s: No signature file specified for verify\n", prog);
        goto end;
    }

    if (pkey_op != EVP_PKEY_OP_DERIVE) {
        in = bio_open_default(infile, 'r', FORMAT_BINARY);
        if (in == NULL)
            goto end;
    }
    out = bio_open_default(outfile, 'w', FORMAT_BINARY);
    if (out == NULL)
        goto end;

    if (sigfile != NULL) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");

        if (sigbio == NULL) {
            BIO_printf(bio_err, "Can't open signature file %s\n", sigfile);
            goto end;
        }
        siglen = bio_to_mem(&sig, keysize * 10, sigbio);
        BIO_free(sigbio);
        if (siglen < 0) {
            BIO_printf(bio_err, "Error reading signature data\n");
            goto end;
        }
    }

    /* Raw input data is handled elsewhere */
    if (in != NULL && !rawin) {
        /* Read the input data */
        buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
        if (buf_inlen < 0) {
            BIO_printf(bio_err, "Error reading input Data\n");
            goto end;
        }
        if (rev) {
            size_t i;
            unsigned char ctmp;
            size_t l = (size_t)buf_inlen;
            for (i = 0; i < l / 2; i++) {
                ctmp = buf_in[i];
                buf_in[i] = buf_in[l - 1 - i];
                buf_in[l - 1 - i] = ctmp;
            }
        }
    }

    /* Sanity check the input if the input is not raw */
    if (!rawin
            && buf_inlen > EVP_MAX_MD_SIZE
            && (pkey_op == EVP_PKEY_OP_SIGN
                || pkey_op == EVP_PKEY_OP_VERIFY
                || pkey_op == EVP_PKEY_OP_VERIFYRECOVER)) {
        BIO_printf(bio_err,
                   "Error: The input data looks too long to be a hash\n");
        goto end;
    }

    if (pkey_op == EVP_PKEY_OP_VERIFY) {
        if (rawin) {
            rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, sig, siglen,
                              NULL, 0);
        } else {
            rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
                                 buf_in, (size_t)buf_inlen);
        }
        if (rv == 1) {
            BIO_puts(out, "Signature Verified Successfully\n");
            ret = 0;
        } else {
            BIO_puts(out, "Signature Verification Failure\n");
        }
        goto end;
    }
    if (kdflen != 0) {
        buf_outlen = kdflen;
        rv = 1;
    } else {
        if (rawin) {
            /* rawin allocates the buffer in do_raw_keyop() */
            rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, NULL, 0,
                              &buf_out, (size_t *)&buf_outlen);
        } else {
            rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
                          buf_in, (size_t)buf_inlen);
            if (rv > 0 && buf_outlen != 0) {
                buf_out = app_malloc(buf_outlen, "buffer output");
                rv = do_keyop(ctx, pkey_op,
                              buf_out, (size_t *)&buf_outlen,
                              buf_in, (size_t)buf_inlen);
            }
        }
    }
    if (rv <= 0) {
        if (pkey_op != EVP_PKEY_OP_DERIVE) {
            BIO_puts(bio_err, "Public Key operation error\n");
        } else {
            BIO_puts(bio_err, "Key derivation failed\n");
        }
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;

    if (asn1parse) {
        if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
            ERR_print_errors(bio_err);
    } else if (hexdump) {
        BIO_dump(out, (char *)buf_out, buf_outlen);
    } else {
        BIO_write(out, buf_out, buf_outlen);
    }

 end:
    EVP_PKEY_CTX_free(ctx);
    release_engine(e);
    BIO_free(in);
    BIO_free_all(out);
    OPENSSL_free(buf_in);
    OPENSSL_free(buf_out);
    OPENSSL_free(sig);
    sk_OPENSSL_STRING_free(pkeyopts);
    sk_OPENSSL_STRING_free(pkeyopts_passin);
    return ret;
}
Example #11
0
int MAIN(int argc, char **argv)
{
	BIO *in = NULL, *out = NULL;
	char *infile = NULL, *outfile = NULL;
	char *keyfile = NULL;
	char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
	int keyform = FORMAT_PEM;
	char need_priv = 0, badarg = 0, rev = 0;
	char hexdump = 0, asn1parse = 0;
	X509 *x;
	EVP_PKEY *pkey = NULL;
	RSA *rsa = NULL;
	unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
	int rsa_inlen, rsa_outlen = 0;
	int keysize;

	int ret = 1;

	argc--;
	argv++;

	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();
	pad = RSA_PKCS1_PADDING;
	
	while(argc >= 1)
	{
		if (!strcmp(*argv,"-in")) {
			if (--argc < 1) badarg = 1;
                        infile= *(++argv);
		} else if (!strcmp(*argv,"-out")) {
			if (--argc < 1) badarg = 1;
			outfile= *(++argv);
		} else if(!strcmp(*argv, "-inkey")) {
			if (--argc < 1) badarg = 1;
			keyfile = *(++argv);
		} else if(!strcmp(*argv, "-pubin")) {
			key_type = KEY_PUBKEY;
		} else if(!strcmp(*argv, "-certin")) {
			key_type = KEY_CERT;
		} 
		else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
		else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
		else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
		else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
		else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
		else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
		else if(!strcmp(*argv, "-sign")) {
			rsa_mode = RSA_SIGN;
			need_priv = 1;
		} else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
		else if(!strcmp(*argv, "-rev")) rev = 1;
		else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
		else if(!strcmp(*argv, "-decrypt")) {
			rsa_mode = RSA_DECRYPT;
			need_priv = 1;
		} else badarg = 1;
		if(badarg) {
			usage();
			goto end;
		}
		argc--;
		argv++;
	}

	if(need_priv && (key_type != KEY_PRIVKEY)) {
		BIO_printf(bio_err, "A private key is needed for this operation\n");
		goto end;
	}

/* FIXME: seed PRNG only if needed */
	app_RAND_load_file(NULL, bio_err, 0);
	
	switch(key_type) {
		case KEY_PRIVKEY:
		pkey = load_key(bio_err, keyfile, keyform, NULL);
		break;

		case KEY_PUBKEY:
		pkey = load_pubkey(bio_err, keyfile, keyform);
		break;

		case KEY_CERT:
		x = load_cert(bio_err, keyfile, keyform);
		if(x) {
			pkey = X509_get_pubkey(x);
			X509_free(x);
		}
		break;
	}

	if(!pkey) {
		BIO_printf(bio_err, "Error loading key\n");
		return 1;
	}

	rsa = EVP_PKEY_get1_RSA(pkey);
	EVP_PKEY_free(pkey);

	if(!rsa) {
		BIO_printf(bio_err, "Error getting RSA key\n");
		ERR_print_errors(bio_err);
		goto end;
	}


	if(infile) {
		if(!(in = BIO_new_file(infile, "rb"))) {
			BIO_printf(bio_err, "Error Reading Input File\n");
			ERR_print_errors(bio_err);	
			goto end;
		}
	} else in = BIO_new_fp(stdin, BIO_NOCLOSE);

	if(outfile) {
		if(!(out = BIO_new_file(outfile, "wb"))) {
			BIO_printf(bio_err, "Error Reading Output File\n");
			ERR_print_errors(bio_err);	
			goto end;
		}
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef VMS
		{
		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		    out = BIO_push(tmpbio, out);
		}
#endif
	}

	keysize = RSA_size(rsa);

	rsa_in = OPENSSL_malloc(keysize * 2);
	rsa_out = OPENSSL_malloc(keysize);

	/* Read the input data */
	rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
	if(rsa_inlen <= 0) {
		BIO_printf(bio_err, "Error reading input Data\n");
		exit(1);
	}
	if(rev) {
		int i;
		unsigned char ctmp;
		for(i = 0; i < rsa_inlen/2; i++) {
			ctmp = rsa_in[i];
			rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
			rsa_in[rsa_inlen - 1 - i] = ctmp;
		}
	}
	switch(rsa_mode) {

		case RSA_VERIFY:
			rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

		case RSA_SIGN:
			rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

		case RSA_ENCRYPT:
			rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

		case RSA_DECRYPT:
			rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	}

	if(rsa_outlen <= 0) {
		BIO_printf(bio_err, "RSA operation error\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	ret = 0;
	if(asn1parse) {
		if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
			ERR_print_errors(bio_err);
		}
	} else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
	else BIO_write(out, rsa_out, rsa_outlen);
	end:
	RSA_free(rsa);
	BIO_free(in);
	BIO_free_all(out);
	if(rsa_in) OPENSSL_free(rsa_in);
	if(rsa_out) OPENSSL_free(rsa_out);
	return ret;
}
int MAIN(int argc, char **argv)
{
	BIO *in = NULL, *out = NULL;
	char *infile = NULL, *outfile = NULL, *sigfile = NULL;
	ENGINE *e = NULL;
	int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
	int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
	char badarg = 0, rev = 0;
	char hexdump = 0, asn1parse = 0;
	EVP_PKEY_CTX *ctx = NULL;
	char *passargin = NULL;
	int keysize = -1;

	unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
	size_t buf_outlen;
	int buf_inlen = 0, siglen = -1;

	int ret = 1, rv = -1;

	argc--;
	argv++;

	if(!bio_err) bio_err = BIO_new_fp(OPENSSL_TYPE__FILE_STDERR, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();
	
	while(argc >= 1)
		{
		if (!TINYCLR_SSL_STRCMP(*argv,"-in"))
			{
			if (--argc < 1) badarg = 1;
                        else infile= *(++argv);
			}
		else if (!TINYCLR_SSL_STRCMP(*argv,"-out"))
			{
			if (--argc < 1) badarg = 1;
			else outfile= *(++argv);
			}
		else if (!TINYCLR_SSL_STRCMP(*argv,"-sigfile"))
			{
			if (--argc < 1) badarg = 1;
			else sigfile= *(++argv);
			}
		else if(!TINYCLR_SSL_STRCMP(*argv, "-inkey"))
			{
			if (--argc < 1)
				badarg = 1;
			else
				{
				ctx = init_ctx(&keysize,
						*(++argv), keyform, key_type,
						passargin, pkey_op, e);
				if (!ctx)
					{
					BIO_puts(bio_err,
						"Error initializing context\n");
					ERR_print_errors(bio_err);
					badarg = 1;
					}
				}
			}
		else if (!TINYCLR_SSL_STRCMP(*argv,"-peerkey"))
			{
			if (--argc < 1)
				badarg = 1;
			else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
				badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*argv,"-passin"))
			{
			if (--argc < 1) badarg = 1;
			else passargin= *(++argv);
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-peerform") == 0)
			{
			if (--argc < 1) badarg = 1;
			else peerform=str2fmt(*(++argv));
			}
		else if (TINYCLR_SSL_STRCMP(*argv,"-keyform") == 0)
			{
			if (--argc < 1) badarg = 1;
			else keyform=str2fmt(*(++argv));
			}
#ifndef OPENSSL_NO_ENGINE
		else if(!TINYCLR_SSL_STRCMP(*argv, "-engine"))
			{
			if (--argc < 1)
				badarg = 1;
			else
				e = setup_engine(bio_err, *(++argv), 0);
			}
#endif
		else if(!TINYCLR_SSL_STRCMP(*argv, "-pubin"))
			key_type = KEY_PUBKEY;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-certin"))
			key_type = KEY_CERT;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-asn1parse"))
			asn1parse = 1;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-hexdump"))
			hexdump = 1;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-sign"))
			pkey_op = EVP_PKEY_OP_SIGN;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-verify"))
			pkey_op = EVP_PKEY_OP_VERIFY;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-verifyrecover"))
			pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-rev"))
			rev = 1;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-encrypt"))
			pkey_op = EVP_PKEY_OP_ENCRYPT;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-decrypt"))
			pkey_op = EVP_PKEY_OP_DECRYPT;
		else if(!TINYCLR_SSL_STRCMP(*argv, "-derive"))
			pkey_op = EVP_PKEY_OP_DERIVE;
		else if (TINYCLR_SSL_STRCMP(*argv,"-pkeyopt") == 0)
			{
			if (--argc < 1)
				badarg = 1;
			else if (!ctx)
				{
				BIO_puts(bio_err,
					"-pkeyopt command before -inkey\n");
				badarg = 1;
				}
			else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
				{
				BIO_puts(bio_err, "parameter setting error\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			}
		else badarg = 1;
		if(badarg)
			{
			usage();
			goto end;
			}
		argc--;
		argv++;
		}

	if (!ctx)
		{
		usage();
		goto end;
		}

	if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
		{
		BIO_puts(bio_err, "Signature file specified for non verify\n");
		goto end;
		}

	if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
		{
		BIO_puts(bio_err, "No signature file specified for verify\n");
		goto end;
		}

/* FIXME: seed PRNG only if needed */
	app_RAND_load_file(NULL, bio_err, 0);

	if (pkey_op != EVP_PKEY_OP_DERIVE)
		{
		if(infile)
			{
			if(!(in = BIO_new_file(infile, "rb")))
				{
				BIO_puts(bio_err,
					"Error Opening Input File\n");
				ERR_print_errors(bio_err);	
				goto end;
				}
			}
		else
			in = BIO_new_fp(OPENSSL_TYPE__FILE_STDIN, BIO_NOCLOSE);
		}

	if(outfile)
		{
		if(!(out = BIO_new_file(outfile, "wb")))
			{
			BIO_printf(bio_err, "Error Creating Output File\n");
			ERR_print_errors(bio_err);	
			goto end;
			}
		}
	else
		{
		out = BIO_new_fp(OPENSSL_TYPE__FILE_STDOUT, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
		{
		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		    out = BIO_push(tmpbio, out);
		}
#endif
	}

	if (sigfile)
		{
		BIO *sigbio = BIO_new_file(sigfile, "rb");
		if (!sigbio)
			{
			BIO_printf(bio_err, "Can't open signature file %s\n",
								sigfile);
			goto end;
			}
		siglen = bio_to_mem(&sig, keysize * 10, sigbio);
		BIO_free(sigbio);
		if (siglen <= 0)
			{
			BIO_printf(bio_err, "Error reading signature data\n");
			goto end;
			}
		}
	
	if (in)
		{
		/* Read the input data */
		buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
		if(buf_inlen <= 0)
			{
			BIO_printf(bio_err, "Error reading input Data\n");
			TINYCLR_SSL_EXIT(1);
			}
		if(rev)
			{
			size_t i;
			unsigned char ctmp;
			size_t l = (size_t)buf_inlen;
			for(i = 0; i < l/2; i++)
				{
				ctmp = buf_in[i];
				buf_in[i] = buf_in[l - 1 - i];
				buf_in[l - 1 - i] = ctmp;
				}
			}
		}

	if(pkey_op == EVP_PKEY_OP_VERIFY)
		{
		rv  = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
				      buf_in, (size_t)buf_inlen);
		if (rv == 0)
			BIO_puts(out, "Signature Verification Failure\n");
		else if (rv == 1)
			BIO_puts(out, "Signature Verified Successfully\n");
		if (rv >= 0)
			goto end;
		}
	else
		{	
		rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
			      buf_in, (size_t)buf_inlen);
		if (rv > 0)
			{
			buf_out = (unsigned char*)OPENSSL_malloc(buf_outlen);
			if (!buf_out)
				rv = -1;
			else
				rv = do_keyop(ctx, pkey_op,
						buf_out, (size_t *)&buf_outlen,
						buf_in, (size_t)buf_inlen);
			}
		}

	if(rv <= 0)
		{
		BIO_printf(bio_err, "Public Key operation error\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret = 0;
	if(asn1parse)
		{
		if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
			ERR_print_errors(bio_err);
		}
	else if(hexdump)
		BIO_dump(out, (char *)buf_out, buf_outlen);
	else
		BIO_write(out, buf_out, buf_outlen);

	end:
	if (ctx)
		EVP_PKEY_CTX_free(ctx);
	BIO_free(in);
	BIO_free_all(out);
	if (buf_in)
		OPENSSL_free(buf_in);
	if (buf_out)
		OPENSSL_free(buf_out);
	if (sig)
		OPENSSL_free(sig);
	return ret;
}
/**
 * @brief Wrap
 * @ingroup globus_gsi_gssapi
 * @details 
 * Wrap a message for integrity and protection.
 * We do this using the SSLv3 routines, by writing to the
 * SSL bio, and pulling off the buffer from the back 
 * of the write BIO.  But we can't do everything SSL 
 * might want, such as control messages, or segment the messages
 * here, since we are forced to using the GSSAPI tokens,
 * and can not communicate directly with our peer. 
 * So there maybe some failures which would work with true
 * SSL. 
 *
 * @param minor_status
 * @param context_handle
 * @param conf_req_flag
 * @param qop_req
 * @param input_message_buffer
 * @param conf_state
 * @param output_message_buffer
 *
 * @return
 */
OM_uint32 
GSS_CALLCONV gss_wrap(
    OM_uint32 *                         minor_status,
    const gss_ctx_id_t                  context_handle,
    int                                 conf_req_flag,
    gss_qop_t                           qop_req,
    const gss_buffer_t                  input_message_buffer,
    int *                               conf_state,
    gss_buffer_t                        output_message_buffer)
{
    gss_ctx_id_desc *                   context =
        (gss_ctx_id_desc *)context_handle; 
    gss_buffer_desc                     mic_buf_desc;
    gss_buffer_t                        mic_buf =
        (gss_buffer_desc *) &mic_buf_desc;
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    unsigned char *                     message_value;
    time_t                              context_goodtill;
    static char *                       _function_name_ =
        "gss_wrap";
    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;
    
    *minor_status = (OM_uint32) GLOBUS_SUCCESS;

    if(GLOBUS_I_GSI_GSSAPI_DEBUG(3))
    {
        BIO *                           debug_bio;
        fprintf(globus_i_gsi_gssapi_debug_fstream,
                "input message: length = %u\n"
                "               value = \n",
                (unsigned) input_message_buffer->length);

        debug_bio = BIO_new_fp(globus_i_gsi_gssapi_debug_fstream,
                               BIO_NOCLOSE);
        BIO_dump(debug_bio,
                 input_message_buffer->value,
                 input_message_buffer->length);
    }

    output_message_buffer->value = NULL;
    output_message_buffer->length = 0;

    GLOBUS_I_GSI_GSSAPI_DEBUG_FPRINTF(
        2, (globus_i_gsi_gssapi_debug_fstream,
            "gss_wrap conf_req_flag=%d qop_req=%d\n",
            conf_req_flag, (int) qop_req));

    if (context_handle == GSS_C_NO_CONTEXT)
    {
        major_status = GSS_S_NO_CONTEXT;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid context handle passed to function")));
        goto exit;
    }

    /* lock the context mutex */
    
    globus_mutex_lock(&context->mutex);

    if(context->ctx_flags & GSS_I_PROTECTION_FAIL_ON_CONTEXT_EXPIRATION)
    {
        time_t                          current_time;

        current_time = time(NULL);

        major_status = globus_i_gsi_gss_get_context_goodtill(
            &local_minor_status,
            context,
            &context_goodtill);
        if(GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT);
            goto unlock_mutex_error;
        }

        if(current_time > context_goodtill)
        {
            major_status = GSS_S_CONTEXT_EXPIRED;
            GLOBUS_GSI_GSSAPI_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_EXPIRED_CREDENTIAL,
                (_GGSL("Expired credential: %s < %s"), 
                 ctime(&context_goodtill), ctime(&current_time)));
            goto unlock_mutex_error;
        }
    }

    if (conf_req_flag == GSS_INTEGRITY_ONLY &&
        qop_req == GSS_C_QOP_GLOBUS_GSSAPI_OPENSSL_BIG)
    {
        /* unlock the context mutex */
        globus_mutex_unlock(&context->mutex);
        
        major_status = gss_get_mic(&local_minor_status,
                                   context_handle,
                                   qop_req,
                                   input_message_buffer,
                                   mic_buf);
        if (GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_MIC);
            goto unlock_mutex_error;
        }

        /* lock the context mutex */
        globus_mutex_lock(&context->mutex);
        
        output_message_buffer->value = 
            (char *) malloc(5 + mic_buf->length + 
                           input_message_buffer->length);
        if (output_message_buffer->value == NULL)
        {
            GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status);
            gss_release_buffer(&local_minor_status, mic_buf);
            major_status = GSS_S_FAILURE;
            goto unlock_mutex_error;
        }

        output_message_buffer->length = 5 + mic_buf->length + 
            input_message_buffer->length;
        message_value = output_message_buffer->value;
        *message_value++ = SSL3_RT_GSSAPI_OPENSSL;
        *message_value++ = 3;
        *message_value++ = 0;
        S2N(mic_buf->length, (char *) message_value);
        message_value += 2;
        memcpy(message_value, mic_buf->value, mic_buf->length);
        message_value = message_value + mic_buf->length;
        memcpy(message_value, input_message_buffer->value,
               input_message_buffer->length);
        
        if (conf_state)
        {
            *conf_state = GSS_INTEGRITY_ONLY;
        }
    } 
    else
    {
        int rc;
        rc = SSL_write(context->gss_ssl,
                       input_message_buffer->value,
                       input_message_buffer->length);
        if (rc != input_message_buffer->length)
        {
            /* problem, did not take the whole buffer */

            GLOBUS_GSI_GSSAPI_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WRAP_BIO,
                (_GGSL("SSL failed wrapping entire message: "
                 "SSL_write wrote %d bytes, should be %d bytes"),
                 rc, input_message_buffer->length));
            major_status = GSS_S_FAILURE;
            goto unlock_mutex_error;
        }
        if (conf_state)
        {
            if (SSL_CIPHER_get_bits(
                    SSL_get_current_cipher(context->gss_ssl), NULL) == 0)
            {
                *conf_state = GSS_INTEGRITY_ONLY;
            }
            else
            {
                *conf_state = GSS_CONFIDENTIALITY;
            }
        }

        /* get the data from the write BIO */
        major_status =  globus_i_gsi_gss_get_token(&local_minor_status,
                                                   context,
                                                   NULL,
                                                   output_message_buffer);
        if(GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_TOKEN_FAIL);
            goto unlock_mutex_error;
        }
    }

 unlock_mutex_error:

    globus_mutex_unlock(&context->mutex);

 exit:

    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}