static int sign_and_verify(int len)
{
    /*
     * Per FIPS 186-4, the hash is recommended to be the same length as q.
     * If the hash is longer than q, the leftmost N bits are used; if the hash
     * is shorter, then we left-pad (see appendix C.2.1).
     */
    size_t sigLength;
    int digestlen = BN_num_bytes(DSA_get0_q(dsakey));
    int ok = 0;

    unsigned char *dataToSign = OPENSSL_malloc(len);
    unsigned char *paddedData = OPENSSL_malloc(digestlen);
    unsigned char *signature = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey = NULL;

    if (!TEST_ptr(dataToSign) ||
        !TEST_ptr(paddedData) ||
        !TEST_int_eq(RAND_bytes(dataToSign, len), 1))
        goto end;

    memset(paddedData, 0, digestlen);
    if (len > digestlen)
        memcpy(paddedData, dataToSign, digestlen);
    else
        memcpy(paddedData + digestlen - len, dataToSign, len);

    if (!TEST_ptr(pkey = EVP_PKEY_new()))
        goto end;
    EVP_PKEY_set1_DSA(pkey, dsakey);

    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
        goto end;
    if (!TEST_int_eq(EVP_PKEY_sign_init(ctx), 1))
        goto end;

    if (EVP_PKEY_sign(ctx, NULL, &sigLength, dataToSign, len) != 1) {
        TEST_error("Failed to get signature length, len=%d", len);
        goto end;
    }

    if (!TEST_ptr(signature = OPENSSL_malloc(sigLength)))
        goto end;

    if (EVP_PKEY_sign(ctx, signature, &sigLength, dataToSign, len) != 1) {
        TEST_error("Failed to sign, len=%d", len);
        goto end;
    }

    /* Check that the signature is okay via the EVP interface */
    if (!TEST_int_eq(EVP_PKEY_verify_init(ctx), 1))
        goto end;

    /* ... using the same data we just signed */
    if (EVP_PKEY_verify(ctx, signature, sigLength, dataToSign, len) != 1) {
        TEST_error("EVP verify with unpadded length %d failed\n", len);
        goto end;
    }

    /* ... padding/truncating the data to the appropriate digest size */
    if (EVP_PKEY_verify(ctx, signature, sigLength, paddedData, digestlen) != 1) {
        TEST_error("EVP verify with length %d failed\n", len);
        goto end;
    }

    /* Verify again using the raw DSA interface */
    if (DSA_verify(0, dataToSign, len, signature, sigLength, dsakey) != 1) {
        TEST_error("Verification with unpadded data failed, len=%d", len);
        goto end;
    }

    if (DSA_verify(0, paddedData, digestlen, signature, sigLength, dsakey) != 1) {
        TEST_error("verify with length %d failed\n", len);
        goto end;
    }

    ok = 1;
end:
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);

    OPENSSL_free(signature);
    OPENSSL_free(paddedData);
    OPENSSL_free(dataToSign);

    return ok;
}
예제 #2
0
int main(int argc, char **argv)
{
	EVP_PKEY *private_key, *public_key;
	EVP_PKEY_CTX *pkey_ctx;
	EVP_MD_CTX *md_ctx;

	const EVP_MD *digest_algo;

	char *private_key_name, *public_key_name;

	unsigned char sig[4096];
	size_t sig_len;

	unsigned char md[128];
	size_t md_len;
	unsigned digest_len;

	char *key_pass = NULL;
	const char *module_path, *efile;

	ENGINE *e;

	int ret;

	if (argc < 5) {
		fprintf(stderr, "usage: %s [PIN] [CONF] [private key URL] [public key URL] [module]\n", argv[0]);
		fprintf(stderr, "\n");
		exit(1);
	}

	key_pass = argv[1];
	efile = argv[2];
	private_key_name = argv[3];
	public_key_name = argv[4];
	module_path = argv[5];

	ret = CONF_modules_load_file(efile, "engines", 0);
	if (ret <= 0) {
		fprintf(stderr, "cannot load %s\n", efile);
		display_openssl_errors(__LINE__);
		exit(1);
	}

	ENGINE_add_conf_module();
#if OPENSSL_VERSION_NUMBER>=0x10100000
	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
		| OPENSSL_INIT_ADD_ALL_DIGESTS \
		| OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
	OpenSSL_add_all_algorithms();
	OpenSSL_add_all_digests();
	ERR_load_crypto_strings();
#endif
	ERR_clear_error();

	ENGINE_load_builtin_engines();
	e = ENGINE_by_id("pkcs11");
	if (e == NULL) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (!ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0)) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (!ENGINE_ctrl_cmd_string(e, "MODULE_PATH", module_path, 0)) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (!ENGINE_init(e)) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (key_pass && !ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);
	if (private_key == NULL) {
		fprintf(stderr, "cannot load: %s\n", private_key_name);
		display_openssl_errors(__LINE__);
		exit(1);
	}

	public_key = ENGINE_load_public_key(e, public_key_name, NULL, NULL);
	if (public_key == NULL) {
		fprintf(stderr, "cannot load: %s\n", public_key_name);
		display_openssl_errors(__LINE__);
		exit(1);
	}

	digest_algo = EVP_get_digestbyname("sha256");

#define TEST_DATA "test data"

	md_ctx = EVP_MD_CTX_create();
	if (EVP_DigestInit(md_ctx, digest_algo) <= 0) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_DigestUpdate(md_ctx, TEST_DATA, sizeof(TEST_DATA)) <= 0) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	digest_len = sizeof(md);
	if (EVP_DigestFinal(md_ctx, md, &digest_len) <= 0) {
		display_openssl_errors(__LINE__);
		exit(1);
	}
	md_len = digest_len;

	EVP_MD_CTX_destroy(md_ctx);

	/* Sign the hash */
	pkey_ctx = EVP_PKEY_CTX_new(private_key, e);

	if (pkey_ctx == NULL) {
		fprintf(stderr, "Could not create context\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_PKEY_sign_init(pkey_ctx) <= 0) {
		fprintf(stderr, "Could not init signature\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
		fprintf(stderr, "Could not set padding\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, digest_algo) <= 0) {
		fprintf(stderr, "Could not set message digest algorithm\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	sig_len = sizeof(sig);
	if (EVP_PKEY_sign(pkey_ctx, sig, &sig_len, md,
			EVP_MD_size(digest_algo)) <= 0) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	EVP_PKEY_CTX_free(pkey_ctx);

	printf("Signature created\n");

#if OPENSSL_VERSION_NUMBER >= 0x1000000fL

	pkey_ctx = EVP_PKEY_CTX_new(public_key, e);

	if (pkey_ctx == NULL) {
		fprintf(stderr, "Could not create context\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_PKEY_verify_init(pkey_ctx) <= 0) {
		fprintf(stderr, "Could not init verify\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
		fprintf(stderr, "Could not set padding\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, digest_algo) <= 0) {
		fprintf(stderr, "Could not set message digest algorithm\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

	ret = EVP_PKEY_verify(pkey_ctx, sig, sig_len, md, md_len);
	if (ret < 0) {
		display_openssl_errors(__LINE__);
		exit(1);
	}

	EVP_PKEY_CTX_free(pkey_ctx);

	if (ret == 1) {
		printf("Signature verified\n");
	}
	else {
		printf("Verification failed\n");
		display_openssl_errors(__LINE__);
		exit(1);
	}

#else /* OPENSSL_VERSION_NUMBER >= 0x1000000fL */

	printf("Unable to verify signature with %s\n", OPENSSL_VERSION_TEXT);

#endif /* OPENSSL_VERSION_NUMBER >= 0x1000000fL */

	ENGINE_finish(e);
	CONF_modules_unload(1);
	return 0;
}
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri;
	CMS_EncryptedContentInfo *ec;
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;

	int ret = 0;

	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ktri = ri->d.ktri;
	ec = cms->d.envelopedData->encryptedContentInfo;

	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
	if (!pctx)
		return 0;

	if (EVP_PKEY_encrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
							ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
		goto err;

	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
	ek = NULL;

	ret = 1;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (ek)
		OPENSSL_free(ek);
	return ret;

	}
예제 #4
0
파일: dgst.c 프로젝트: AshKarath/bumo
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL, *impl = NULL;
    unsigned char *buf = NULL;
    int i, err = 1;
    const EVP_MD *md = NULL, *m;
    BIO *in = NULL, *inp;
    BIO *bmd = NULL;
    BIO *out = NULL;
#define PROG_NAME_SIZE  39
    char pname[PROG_NAME_SIZE + 1];
    int separator = 0;
    int debug = 0;
    int keyform = FORMAT_PEM;
    const char *outfile = NULL, *keyfile = NULL;
    const char *sigfile = NULL, *randfile = NULL;
    int out_bin = -1, want_pub = 0, do_verify = 0;
    EVP_PKEY *sigkey = NULL;
    unsigned char *sigbuf = NULL;
    int siglen = 0;
    char *passargin = NULL, *passin = NULL;
#ifndef OPENSSL_NO_ENGINE
    char *engine = NULL;
    int engine_impl = 0;
#endif
    char *hmac_key = NULL;
    char *mac_name = NULL;
    int non_fips_allow = 0;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;

    apps_startup();

    if ((buf = (unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) {
        BIO_printf(bio_err, "out of memory\n");
        goto end;
    }
    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;

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

    md = EVP_get_digestbyname(pname);

    argc--;
    argv++;
    while (argc > 0) {
        if ((*argv)[0] != '-')
            break;
        if (strcmp(*argv, "-c") == 0)
            separator = 1;
        else if (strcmp(*argv, "-r") == 0)
            separator = 2;
        else if (strcmp(*argv, "-rand") == 0) {
            if (--argc < 1)
                break;
            randfile = *(++argv);
        } else if (strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                break;
            outfile = *(++argv);
        } else if (strcmp(*argv, "-sign") == 0) {
            if (--argc < 1)
                break;
            keyfile = *(++argv);
        } else if (!strcmp(*argv, "-passin")) {
            if (--argc < 1)
                break;
            passargin = *++argv;
        } else if (strcmp(*argv, "-verify") == 0) {
            if (--argc < 1)
                break;
            keyfile = *(++argv);
            want_pub = 1;
            do_verify = 1;
        } else if (strcmp(*argv, "-prverify") == 0) {
            if (--argc < 1)
                break;
            keyfile = *(++argv);
            do_verify = 1;
        } else if (strcmp(*argv, "-signature") == 0) {
            if (--argc < 1)
                break;
            sigfile = *(++argv);
        } else if (strcmp(*argv, "-keyform") == 0) {
            if (--argc < 1)
                break;
            keyform = str2fmt(*(++argv));
        }
#ifndef OPENSSL_NO_ENGINE
        else if (strcmp(*argv, "-engine") == 0) {
            if (--argc < 1)
                break;
            engine = *(++argv);
            e = setup_engine(bio_err, engine, 0);
        } else if (strcmp(*argv, "-engine_impl") == 0)
            engine_impl = 1;
#endif
        else if (strcmp(*argv, "-hex") == 0)
            out_bin = 0;
        else if (strcmp(*argv, "-binary") == 0)
            out_bin = 1;
        else if (strcmp(*argv, "-d") == 0)
            debug = 1;
        else if (!strcmp(*argv, "-fips-fingerprint"))
            hmac_key = "etaonrishdlcupfm";
        else if (strcmp(*argv, "-non-fips-allow") == 0)
            non_fips_allow = 1;
        else if (!strcmp(*argv, "-hmac")) {
            if (--argc < 1)
                break;
            hmac_key = *++argv;
        } else if (!strcmp(*argv, "-mac")) {
            if (--argc < 1)
                break;
            mac_name = *++argv;
        } else if (strcmp(*argv, "-sigopt") == 0) {
            if (--argc < 1)
                break;
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
                break;
        } else if (strcmp(*argv, "-macopt") == 0) {
            if (--argc < 1)
                break;
            if (!macopts)
                macopts = sk_OPENSSL_STRING_new_null();
            if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
                break;
        } else if ((m = EVP_get_digestbyname(&((*argv)[1]))) != NULL)
            md = m;
        else
            break;
        argc--;
        argv++;
    }

    if (keyfile != NULL && argc > 1) {
        BIO_printf(bio_err, "Can only sign or verify one file\n");
        goto end;
    }

    if (do_verify && !sigfile) {
        BIO_printf(bio_err,
                   "No signature to verify: use the -signature option\n");
        goto end;
    }

    if ((argc > 0) && (argv[0][0] == '-')) { /* bad option */
        BIO_printf(bio_err, "unknown option '%s'\n", *argv);
        BIO_printf(bio_err, "options are\n");
        BIO_printf(bio_err,
                   "-c              to output the digest with separating colons\n");
        BIO_printf(bio_err,
                   "-r              to output the digest in coreutils format\n");
        BIO_printf(bio_err, "-d              to output debug info\n");
        BIO_printf(bio_err, "-hex            output as hex dump\n");
        BIO_printf(bio_err, "-binary         output in binary form\n");
        BIO_printf(bio_err, "-hmac arg       set the HMAC key to arg\n");
        BIO_printf(bio_err, "-non-fips-allow allow use of non FIPS digest\n");
        BIO_printf(bio_err,
                   "-sign   file    sign digest using private key in file\n");
        BIO_printf(bio_err,
                   "-verify file    verify a signature using public key in file\n");
        BIO_printf(bio_err,
                   "-prverify file  verify a signature using private key in file\n");
        BIO_printf(bio_err,
                   "-keyform arg    key file format (PEM or ENGINE)\n");
        BIO_printf(bio_err,
                   "-out filename   output to filename rather than stdout\n");
        BIO_printf(bio_err, "-signature file signature to verify\n");
        BIO_printf(bio_err, "-sigopt nm:v    signature parameter\n");
        BIO_printf(bio_err, "-hmac key       create hashed MAC with key\n");
        BIO_printf(bio_err,
                   "-mac algorithm  create MAC (not neccessarily HMAC)\n");
        BIO_printf(bio_err,
                   "-macopt nm:v    MAC algorithm parameters or key\n");
#ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err,
                   "-engine e       use engine e, possibly a hardware device.\n");
#endif

        EVP_MD_do_all_sorted(list_md_fn, bio_err);
        goto end;
    }
#ifndef OPENSSL_NO_ENGINE
    if (engine_impl)
        impl = e;
#endif

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

    if (debug) {
        BIO_set_callback(in, BIO_debug_callback);
        /* needed for windows 3.1 */
        BIO_set_callback_arg(in, (char *)bio_err);
    }

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

    if (out_bin == -1) {
        if (keyfile)
            out_bin = 1;
        else
            out_bin = 0;
    }

    if (randfile)
        app_RAND_load_file(randfile, bio_err, 0);

    if (outfile) {
        if (out_bin)
            out = BIO_new_file(outfile, "wb");
        else
            out = BIO_new_file(outfile, "w");
    } 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 (!out) {
        BIO_printf(bio_err, "Error opening output file %s\n",
                   outfile ? outfile : "(stdout)");
        ERR_print_errors(bio_err);
        goto end;
    }
    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        goto end;
    }

    if (keyfile) {
        if (want_pub)
            sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
                                 e, "key file");
        else
            sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
                              e, "key file");
        if (!sigkey) {
            /*
             * load_[pub]key() has already printed an appropriate message
             */
            goto end;
        }
    }

    if (mac_name) {
        EVP_PKEY_CTX *mac_ctx = NULL;
        int r = 0;
        if (!init_gen_str(bio_err, &mac_ctx, mac_name, impl, 0))
            goto mac_end;
        if (macopts) {
            char *macopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
                macopt = sk_OPENSSL_STRING_value(macopts, i);
                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
                    BIO_printf(bio_err,
                               "MAC parameter error \"%s\"\n", macopt);
                    ERR_print_errors(bio_err);
                    goto mac_end;
                }
            }
        }
        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
            BIO_puts(bio_err, "Error generating key\n");
            ERR_print_errors(bio_err);
            goto mac_end;
        }
        r = 1;
 mac_end:
        if (mac_ctx)
            EVP_PKEY_CTX_free(mac_ctx);
        if (r == 0)
            goto end;
    }

    if (non_fips_allow) {
        EVP_MD_CTX *md_ctx;
        BIO_get_md_ctx(bmd, &md_ctx);
        EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
    }

    if (hmac_key) {
        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
                                      (unsigned char *)hmac_key, -1);
        if (!sigkey)
            goto end;
    }

    if (sigkey) {
        EVP_MD_CTX *mctx = NULL;
        EVP_PKEY_CTX *pctx = NULL;
        int r;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (do_verify)
            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
        else
            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
        if (!r) {
            BIO_printf(bio_err, "Error setting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (sigopts) {
            char *sigopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
                    ERR_print_errors(bio_err);
                    goto end;
                }
            }
        }
    }
    /* we use md as a filter, reading from 'in' */
    else {
        EVP_MD_CTX *mctx = NULL;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (md == NULL)
            md = EVP_md5();
        if (!EVP_DigestInit_ex(mctx, md, impl)) {
            BIO_printf(bio_err, "Error setting digest %s\n", pname);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (sigfile && sigkey) {
        BIO *sigbio;
        sigbio = BIO_new_file(sigfile, "rb");
        siglen = EVP_PKEY_size(sigkey);
        sigbuf = OPENSSL_malloc(siglen);
        if (!sigbio) {
            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        if (!sigbuf) {
            BIO_printf(bio_err, "Out of memory\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        siglen = BIO_read(sigbio, sigbuf, siglen);
        BIO_free(sigbio);
        if (siglen <= 0) {
            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    inp = BIO_push(bmd, in);

    if (md == NULL) {
        EVP_MD_CTX *tctx;
        BIO_get_md_ctx(bmd, &tctx);
        md = EVP_MD_CTX_md(tctx);
    }

    if (argc == 0) {
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
        err = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                    siglen, NULL, NULL, "stdin", bmd);
    } else {
        const char *md_name = NULL, *sig_name = NULL;
        if (!out_bin) {
            if (sigkey) {
                const EVP_PKEY_ASN1_METHOD *ameth;
                ameth = EVP_PKEY_get0_asn1(sigkey);
                if (ameth)
                    EVP_PKEY_asn1_get0_info(NULL, NULL,
                                            NULL, NULL, &sig_name, ameth);
            }
            if (md)
                md_name = EVP_MD_name(md);
        }
        err = 0;
        for (i = 0; i < argc; i++) {
            int r;
            if (BIO_read_filename(in, argv[i]) <= 0) {
                perror(argv[i]);
                err++;
                continue;
            } else
                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                          siglen, sig_name, md_name, argv[i], bmd);
            if (r)
                err = r;
            (void)BIO_reset(bmd);
        }
    }
 end:
    if (buf != NULL) {
        OPENSSL_cleanse(buf, BUFSIZE);
        OPENSSL_free(buf);
    }
    if (in != NULL)
        BIO_free(in);
    if (passin)
        OPENSSL_free(passin);
    BIO_free_all(out);
    EVP_PKEY_free(sigkey);
    if (sigopts)
        sk_OPENSSL_STRING_free(sigopts);
    if (macopts)
        sk_OPENSSL_STRING_free(macopts);
    if (sigbuf)
        OPENSSL_free(sigbuf);
    if (bmd != NULL)
        BIO_free(bmd);
    apps_shutdown();
    OPENSSL_EXIT(err);
}
예제 #5
0
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
                              char *keyfile, int keyform, int key_type,
                              char *passargin, int pkey_op, ENGINE *e)
{
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    char *passin = NULL;
    int rv = -1;
    X509 *x;
    if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
         || (pkey_op == EVP_PKEY_OP_DERIVE))
        && (key_type != KEY_PRIVKEY)) {
        BIO_printf(bio_err, "A private key is needed for this operation\n");
        goto end;
    }
    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;

    }

    *pkeysize = EVP_PKEY_size(pkey);

    if (!pkey)
        goto end;

    ctx = EVP_PKEY_CTX_new(pkey, e);

    EVP_PKEY_free(pkey);

    if (!ctx)
        goto end;

    switch (pkey_op) {
    case EVP_PKEY_OP_SIGN:
        rv = EVP_PKEY_sign_init(ctx);
        break;

    case EVP_PKEY_OP_VERIFY:
        rv = EVP_PKEY_verify_init(ctx);
        break;

    case EVP_PKEY_OP_VERIFYRECOVER:
        rv = EVP_PKEY_verify_recover_init(ctx);
        break;

    case EVP_PKEY_OP_ENCRYPT:
        rv = EVP_PKEY_encrypt_init(ctx);
        break;

    case EVP_PKEY_OP_DECRYPT:
        rv = EVP_PKEY_decrypt_init(ctx);
        break;

    case EVP_PKEY_OP_DERIVE:
        rv = EVP_PKEY_derive_init(ctx);
        break;
    }

    if (rv <= 0) {
        EVP_PKEY_CTX_free(ctx);
        ctx = NULL;
    }

 end:

    if (passin)
        OPENSSL_free(passin);

    return ctx;

}
예제 #6
0
U8_EXPORT ssize_t u8_cryptic
(int do_encrypt,const char *cname,
 const unsigned char *key,int keylen,
 const unsigned char *iv,int ivlen,
 u8_block_reader reader,u8_block_writer writer,
 void *readstate,void *writestate,
 u8_context caller)
{
  if (strncasecmp(cname,"rsa",3)==0) {
    ENGINE *eng=ENGINE_get_default_RSA();
    EVP_PKEY _pkey, *pkey; EVP_PKEY_CTX *ctx; 
    int pubkeyin=(strncasecmp(cname,"rsapub",6)==0);
    const unsigned char *scankey=key;
    struct U8_BYTEBUF bb;
    int retval=-1;
    if (pubkeyin) pkey=d2i_PUBKEY(NULL,&scankey,keylen);
    else pkey=d2i_PrivateKey((EVP_PKEY_RSA),NULL,&scankey,keylen);
    if (!(pkey)) ctx=NULL;
    else {
#if (OPENSSL_VERSION_NUMBER>=0x1000204fL)
      ctx=EVP_PKEY_CTX_new(pkey,eng);
#else
      ctx=EVP_PKEY_CTX_new(pkey,NULL);
#endif
    }
    if (ctx) {
      memset(&bb,0,sizeof(bb));
      bb.u8_direction=u8_output_buffer;
      bb.u8_buf=bb.u8_ptr=(u8_byte *)u8_malloc(1024);
      bb.u8_lim=(u8_byte *)(bb.u8_buf+1024);
      bb.u8_growbuf=1;
      fill_bytebuf(&bb,reader,readstate);}
    if (!(ctx)) {}
    else if ((pubkeyin)?
	     ((do_encrypt)?((retval=EVP_PKEY_encrypt_init(ctx))<0):
	      ((retval=EVP_PKEY_verify_recover_init(ctx))<0)):
	     ((do_encrypt)?((retval=EVP_PKEY_sign_init(ctx))<0):
	      ((retval=EVP_PKEY_decrypt_init(ctx))<0))) {}
    else {
      unsigned char *in=bb.u8_buf; size_t inlen=bb.u8_ptr-bb.u8_buf;
      unsigned char *out=NULL; size_t outlen;
      if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,NULL,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,NULL,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,NULL,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,NULL,&outlen,in,inlen);
      if (retval<0) {}
      else if ((out=u8_malloc(outlen))==NULL) {}
      else if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,out,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,out,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,out,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,out,&outlen,in,inlen);
      if (retval<0) {}
      else retval=writer(out,outlen,writestate);
      if (out) u8_free(out);}
    u8_free(bb.u8_buf);
    if (retval<0) {
      unsigned long err=ERR_get_error(); char buf[512];
      buf[0]='\0'; ERR_error_string_n(err,buf,512);
      u8_seterr(u8_InternalCryptoError,OPENSSL_CRYPTIC,u8_fromlibc((char *)buf));
      ERR_clear_error();}
    if (ctx) EVP_PKEY_CTX_free(ctx);
    if (pkey)  EVP_PKEY_free(pkey);
    return retval;}
  else {
    EVP_CIPHER_CTX ctx;
    int inlen, outlen, retval=0;
    ssize_t totalout=0, totalin=0;
    unsigned char inbuf[1024], outbuf[1024+EVP_MAX_BLOCK_LENGTH];
    const EVP_CIPHER *cipher=((cname)?(EVP_get_cipherbyname(cname)):
			      (EVP_aes_128_cbc()));

    if (cipher) {
      int needkeylen=EVP_CIPHER_key_length(cipher);
      int needivlen=EVP_CIPHER_iv_length(cipher);
      int blocksize=EVP_CIPHER_block_size(cipher);
      if (blocksize>1024) blocksize=1024;
      u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	     " %s cipher=%s, keylen=%d/%d, ivlen=%d/%d, blocksize=%d\n",
	     ((do_encrypt)?("encrypt"):("decrypt")),
	     cname,keylen,needkeylen,ivlen,needivlen,blocksize);

      if ((needivlen)&&(ivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      memset(&ctx,0,sizeof(ctx));

      EVP_CIPHER_CTX_init(&ctx);

      retval=EVP_CipherInit(&ctx, cipher, NULL, NULL, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      retval=EVP_CIPHER_CTX_set_key_length(&ctx,keylen);
      if (retval==0)
	return u8_reterr(u8_BadCryptoKey,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",keylen,needkeylen,cname));

      if ((needivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      retval=EVP_CipherInit(&ctx, cipher, key, iv, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      while (1) {
	inlen = reader(inbuf,blocksize,readstate);
	if (inlen <= 0) {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "Finished %s(%s) with %ld in, %ld out",
		 ((do_encrypt)?("encrypt"):("decrypt")),
		 cname,totalin,totalout);
	  break;}
	else totalin=totalin+inlen;
	if (!(EVP_CipherUpdate(&ctx,outbuf,&outlen,inbuf,inlen))) {
	  char *details=u8_malloc(256);
	  unsigned long err=ERR_get_error();
	  ERR_error_string_n(err,details,256);
	  EVP_CIPHER_CTX_cleanup(&ctx);
	  return u8_reterr(u8_InternalCryptoError,
			   ((caller)?(caller):((u8_context)"u8_cryptic")),
			   details);}
	else {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes"
		 " in=<%v>\n out=<%v>",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 inlen,totalin,outlen,totalout+outlen,
		 inbuf,inlen,outbuf,outlen);
	  writer(outbuf,outlen,writestate);
	  totalout=totalout+outlen;}}
      if (!(EVP_CipherFinal(&ctx,outbuf,&outlen))) {
	char *details=u8_malloc(256);
	unsigned long err=ERR_get_error();
	ERR_error_string_n(err,details,256);
	EVP_CIPHER_CTX_cleanup(&ctx);
	return u8_reterr(u8_InternalCryptoError,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 details);}
      else {
	writer(outbuf,outlen,writestate);
	u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	       "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes"
	       "\n final out=<%v>",
	       ((do_encrypt)?("encrypt"):("decrypt")),cname,
	       inlen,totalin,outlen,totalout+outlen,
	       outbuf,outlen);
	EVP_CIPHER_CTX_cleanup(&ctx);
	totalout=totalout+outlen;
	return totalout;}}
    else {
      char *details=u8_malloc(256);
      unsigned long err=ERR_get_error();
      ERR_error_string_n(err,details,256);
      return u8_reterr("Unknown cipher",
		       ((caller)?(caller):((u8_context)"u8_cryptic")),
		       details);}
  }
}
예제 #7
0
// Key factory
bool OSSLGOST::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
{
	// Check parameters
	if ((ppKeyPair == NULL) ||
	    (parameters == NULL))
	{
		return false;
	}

	if (!parameters->areOfType(ECParameters::type))
	{
		ERROR_MSG("Invalid parameters supplied for GOST key generation");

		return false;
	}

	ECParameters* params = (ECParameters*) parameters;
	ByteString paramA = "06072a850302022301";
	if (params->getEC() != paramA)
	{
		ERROR_MSG("unsupported parameters");

		return false;
	}

	// Generate the key-pair
	EVP_PKEY_CTX* ctx = NULL;
	EVP_PKEY* pkey = NULL;
	OSSLGOSTKeyPair* kp;

	ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL);
	if (ctx == NULL)
	{
		ERROR_MSG("EVP_PKEY_CTX_new_id failed");

		goto err;
	}
	if (EVP_PKEY_keygen_init(ctx) <= 0)
	{
		ERROR_MSG("EVP_PKEY_keygen_init failed");

		goto err;
	}
	if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0)
	{
		ERROR_MSG("EVP_PKEY_CTX_ctrl_str failed");

		goto err;
	}
	if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
	{
		ERROR_MSG("EVP_PKEY_keygen failed");

		goto err;
	}
	EVP_PKEY_CTX_free(ctx);
	ctx = NULL;

	// Create an asymmetric key-pair object to return
	kp = new OSSLGOSTKeyPair();

	((OSSLGOSTPublicKey*) kp->getPublicKey())->setFromOSSL(pkey);
	((OSSLGOSTPrivateKey*) kp->getPrivateKey())->setFromOSSL(pkey);

	*ppKeyPair = kp;

	// Release the key
	EVP_PKEY_free(pkey);

	return true;

err:
	if (ctx != NULL)
		EVP_PKEY_CTX_free(ctx);
	if (pkey != NULL)
		EVP_PKEY_free(pkey);

	return false;
}
예제 #8
0
파일: jwk.c 프로젝트: tgorol/cjose
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(
        cjose_jwk_t *jwk_self,
        cjose_jwk_t *jwk_peer,
        cjose_err *err) 
{
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey_self = NULL;
    EVP_PKEY *pkey_peer = NULL;
    uint8_t *secret = NULL;
    size_t secret_len = 0;
    uint8_t *ephemeral_key = NULL;
    size_t ephemeral_key_len = 0;
    cjose_jwk_t *jwk_ephemeral_key = NULL;

    // get EVP_KEY from jwk_self
    if (!_cjose_jwk_evp_key_from_ec_key(jwk_self, &pkey_self, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // get EVP_KEY from jwk_peer
    if (!_cjose_jwk_evp_key_from_ec_key(jwk_peer, &pkey_peer, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // create derivation context based on local key pair
    ctx = EVP_PKEY_CTX_new(pkey_self, NULL);
    if (NULL == ctx)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // initialize derivation context
    if (1 != EVP_PKEY_derive_init(ctx))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // provide the peer public key
    if (1 != EVP_PKEY_derive_set_peer(ctx, pkey_peer))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // determine buffer length for shared secret
    if(1 != EVP_PKEY_derive(ctx, NULL, &secret_len))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // allocate buffer for shared secret
    secret = (uint8_t *)cjose_get_alloc()(secret_len);
    if (NULL == secret)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jwk_derive_shared_secret_fail;        
    }
    memset(secret, 0, secret_len);

    // derive the shared secret
    if (1 != (EVP_PKEY_derive(ctx, secret, &secret_len)))
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jwk_derive_shared_secret_fail;                
    }

    // HKDF of the DH shared secret (SHA256, no salt, no info, 256 bit expand)
    ephemeral_key_len = 32;
    ephemeral_key = (uint8_t *)cjose_get_alloc()(ephemeral_key_len);
    if (!cjose_jwk_hkdf(EVP_sha256(), (uint8_t *)"", 0, (uint8_t *)"", 0, 
            secret, secret_len, ephemeral_key, ephemeral_key_len, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;        
    }

    // create a JWK of the shared secret
    jwk_ephemeral_key = cjose_jwk_create_oct_spec(
            ephemeral_key, ephemeral_key_len, err);
    if (NULL == jwk_ephemeral_key)
    {
        goto _cjose_jwk_derive_shared_secret_fail;        
    }

    // happy path
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey_self);
    EVP_PKEY_free(pkey_peer);
    cjose_get_dealloc()(secret);
    cjose_get_dealloc()(ephemeral_key);

    return jwk_ephemeral_key;

    // fail path
    _cjose_jwk_derive_shared_secret_fail:
    
    if (NULL != ctx)
    {
        EVP_PKEY_CTX_free(ctx);
    }
    if (NULL != pkey_self)
    {
        EVP_PKEY_free(pkey_self);
    }
    if (NULL != pkey_peer)
    {
        EVP_PKEY_free(pkey_peer);
    }
    if (NULL != jwk_ephemeral_key)
    {
        cjose_jwk_release(jwk_ephemeral_key);
    }
    cjose_get_dealloc()(secret);
    cjose_get_dealloc()(ephemeral_key);
    return NULL;
}
예제 #9
0
파일: pk7_doit.c 프로젝트: hlcherub/src
static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
			       PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
	{
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;

	int ret = -1;

	pctx = EVP_PKEY_CTX_new(pkey, NULL);
	if (!pctx)
		return -1;

	if (EVP_PKEY_decrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
				EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
				ri->enc_key->data, ri->enc_key->length) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
				ri->enc_key->data, ri->enc_key->length) <= 0)
		{
		ret = 0;
		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
		goto err;
		}

	ret = 1;

	if (*pek)
		{
		OPENSSL_cleanse(*pek, *peklen);
		OPENSSL_free(*pek);
		}

	*pek = ek;
	*peklen = eklen;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (!ret && ek)
		OPENSSL_free(ek);

	return ret;
	}
예제 #10
0
파일: utils.c 프로젝트: zarelit/dgproto
int verify(const char* keypath, BIGNUM* nonce, const uint8_t* sig, size_t slen){
    // Nonce
    uint8_t* N;
    size_t Nlen;

    // Context and key
    EVP_PKEY_CTX *verctx;
    FILE* vkeyfh;
    EVP_PKEY *vkey=NULL;

    // Return codes and errors
    int err_code, ret_val=1;
    unsigned long vererr;

    /*
     * Open the public key of the client for verification
     */
    vkeyfh = fopen(keypath,"r");
    if(!vkeyfh)
    {
        fprintf(stderr, "%s: Cannot open the key file\n", __func__);
        ret_val = 0;
        goto exit_verify;
    }
    vkey = PEM_read_PUBKEY(vkeyfh, &vkey, NULL, NULL);
    if(!vkey){
        fprintf(stderr,"Cannot read verification key from file %s\n", keypath);
        ret_val = 0;
        fclose(vkeyfh);
        goto exit_verify;
    }

    verctx = EVP_PKEY_CTX_new(vkey, NULL);
    if (!verctx){
        fprintf(stderr,"Cannot create a verify context\n");
        ret_val = 0;
        fclose(vkeyfh);
        EVP_PKEY_free(vkey);
        goto exit_verify;
    }

    if (EVP_PKEY_verify_init(verctx) <= 0){
        fprintf(stderr,"Cannot initialize a verify context\n");
        ret_val = 0;
        goto cleanup_verify;
    }

    /*
     * Convert the nonce in a string so that it can be verified
     */
    N = malloc(BN_num_bytes(nonce));
    if (N == NULL)
    {
        fprintf(stderr, "%s: Out of memory\n", __func__);
        ret_val = 0;
        goto cleanup_verify;
    }
    Nlen = BN_bn2bin(nonce, N);

    /* Perform actual verify operation */
    err_code = EVP_PKEY_verify(verctx, sig, slen, N, Nlen);
    if( err_code != 1 ){
        ERR_load_crypto_strings();
        vererr = ERR_get_error();
        fprintf(stderr,"The verify operation on the nonce has failed with code %lu. RET=%d\n",vererr,err_code);
        fprintf(stderr,"%s\n", ERR_error_string(vererr, NULL));
        ERR_free_strings();
        ret_val = 0;
    }
    free(N);

cleanup_verify:
    EVP_PKEY_CTX_free(verctx);
    EVP_PKEY_free(vkey);
    fclose(vkeyfh);

exit_verify:
    return ret_val;
}
예제 #11
0
static int test_kdf_scrypt(void)
{
    int ret = 0;
    EVP_PKEY_CTX *pctx;
    unsigned char out[64];
    size_t outlen = sizeof(out);

    if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL)) == NULL) {
        TEST_error("EVP_PKEY_SCRYPT");
        goto err;
    }
    if (EVP_PKEY_derive_init(pctx) <= 0) {
        TEST_error("EVP_PKEY_derive_init");
        goto err;
    }
    if (EVP_PKEY_CTX_set1_pbe_pass(pctx, "password", 8) <= 0) {
        TEST_error("EVP_PKEY_CTX_set1_pbe_pass");
        goto err;
    }
    if (EVP_PKEY_CTX_set1_scrypt_salt(pctx, "NaCl", 4) <= 0) {
        TEST_error("EVP_PKEY_CTX_set1_scrypt_salt");
        goto err;
    }
    if (EVP_PKEY_CTX_set_scrypt_N(pctx, 1024) <= 0) {
        TEST_error("EVP_PKEY_CTX_set_scrypt_N");
        goto err;
    }
    if (EVP_PKEY_CTX_set_scrypt_r(pctx, 8) <= 0) {
        TEST_error("EVP_PKEY_CTX_set_scrypt_r");
        goto err;
    }
    if (EVP_PKEY_CTX_set_scrypt_p(pctx, 16) <= 0) {
        TEST_error("EVP_PKEY_CTX_set_scrypt_p");
        goto err;
    }
    if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 16) <= 0) {
        TEST_error("EVP_PKEY_CTX_set_maxmem_bytes");
        goto err;
    }
    if (EVP_PKEY_derive(pctx, out, &outlen) > 0) {
        TEST_error("EVP_PKEY_derive should have failed");
        goto err;
    }
    if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 10 * 1024 * 1024) <= 0) {
        TEST_error("EVP_PKEY_CTX_set_maxmem_bytes");
        goto err;
    }
    if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) {
        TEST_error("EVP_PKEY_derive");
        goto err;
    }

    {
        const unsigned char expected[sizeof(out)] = {
            0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
            0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
            0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
            0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62,
            0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88,
            0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda,
            0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d,
            0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40
        };
        if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
            goto err;
        }
    }
    ret = 1;
err:
    EVP_PKEY_CTX_free(pctx);
    return ret;
}
예제 #12
0
파일: utils.c 프로젝트: zarelit/dgproto
uint8_t* sign(const char* keypath, const uint8_t* payload, const size_t plen, size_t* slen){

    FILE* ckeyfh;
    EVP_PKEY* ckey=NULL;
    EVP_PKEY_CTX* sigctx;
    uint8_t *sig;

    // Load signing key
    ckeyfh = fopen(keypath,"r");
    if(!ckeyfh)
    {
        fprintf(stderr, "%s: Cannot open the key file\n", __func__);
        sig = NULL;
        goto exit_sign;
    }
    ckey = PEM_read_PrivateKey(ckeyfh, &ckey, NULL, NULL);
    if(!ckey){
        fprintf(stderr,"Cannot read signing key from file %s\n", keypath);
        fclose(ckeyfh);
        sig = NULL;
        goto exit_sign;
    }

    // create signing context
    sigctx = EVP_PKEY_CTX_new(ckey, NULL);
    if (!sigctx){
        fprintf(stderr,"Cannot create a signing context\n");
        fclose(ckeyfh);
        sig = NULL;
        EVP_PKEY_free(ckey);
        goto exit_sign;
    }
    if (EVP_PKEY_sign_init(sigctx) <= 0){
        fprintf(stderr,"Cannot inizialize a signing context\n");
        sig = NULL;
        goto cleanup_sign;
    }

    // Ask the maximum signature size that will result in signing the payload
    if (EVP_PKEY_sign(sigctx, NULL, slen, payload, plen ) <= 0)
    {
        fprintf(stderr, "%s: Cannot get signature size\n", __func__);
        sig = NULL;
        goto cleanup_sign;
    }

    sig = malloc(*slen);
    if(!sig){
        fprintf(stderr,"Out of memory\n");
        goto cleanup_sign;
    }

    // Do the real signature
    if (EVP_PKEY_sign(sigctx, sig, slen, payload, plen) <= 0){
        ERR_load_crypto_strings();
        fprintf(stderr,"Signing operation failed\n");
        printf("%s\n", ERR_error_string(ERR_get_error(), NULL));
        ERR_free_strings();
        sig = NULL;
    }

cleanup_sign:
    fclose(ckeyfh);
    EVP_PKEY_CTX_free(sigctx);
    EVP_PKEY_free(ckey);

exit_sign:
    return sig;
}
static VALUE ORPV__verify_pss_sha1(VALUE self, VALUE vPubKey, VALUE vSig, VALUE vHashData, VALUE vSaltLen) {
  enum ORPV_errors err = OK;

  BIO * pkey_bio = NULL;
  RSA * rsa_pub_key = NULL;
  EVP_PKEY * pkey = NULL;
  EVP_PKEY_CTX * pkey_ctx = NULL;
  char * pub_key = NULL;
  
  int verify_rval = -1, salt_len;
  char ossl_err_strs[(OSSL_ERR_STR_LEN + 2) * ORPV_MAX_ERRS] = "";

  if (ERR_peek_error()) {
    err = EXTERNAL;
    goto Cleanup;
  }

  vPubKey = StringValue(vPubKey);
  vSig = StringValue(vSig);
  vHashData = StringValue(vHashData);
  salt_len = NUM2INT(vSaltLen);

  if (RSTRING_LEN(vPubKey) > (long)INT_MAX) {
    err = KEY_OVERFLOW;
    goto Cleanup;
  }

  pub_key = malloc(RSTRING_LEN(vPubKey));
  if (! pub_key) {
    err = NOMEM;
    goto Cleanup;
  }
  memcpy(pub_key, StringValuePtr(vPubKey), RSTRING_LEN(vPubKey));

  pkey_bio = BIO_new_mem_buf(pub_key, (int)RSTRING_LEN(vPubKey));
  rsa_pub_key = PEM_read_bio_RSA_PUBKEY(pkey_bio, NULL, NULL, NULL);
  if (! rsa_pub_key) {
    err = PUBKEY_PARSE;
    goto Cleanup;
  }

  pkey = EVP_PKEY_new();
  if (! pkey) {
    err = PKEY_INIT;
    goto Cleanup;
  }

  if (! EVP_PKEY_set1_RSA(pkey, rsa_pub_key)) {
    err = RSA_ASSIGN;
    goto Cleanup;
  }

  pkey_ctx = EVP_PKEY_CTX_new(pkey, ENGINE_get_default_RSA());
  if (! pkey_ctx) {
    err = PKEY_CTX_INIT;
    goto Cleanup;
  }

  if (EVP_PKEY_verify_init(pkey_ctx) <= 0) {
    err = VERIFY_INIT;
    goto Cleanup;
  }

  if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, EVP_sha1()) <= 0) {
    err = SET_SIG_MD;
    goto Cleanup;
  }

  if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
    err = SET_PADDING;
    goto Cleanup;
  }

  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) <= 0) {
    err = SET_SALTLEN;
    goto Cleanup;
  }

  verify_rval = EVP_PKEY_verify(pkey_ctx, 
                                (unsigned char*)StringValuePtr(vSig), (size_t)RSTRING_LEN(vSig), 
                                (unsigned char*)StringValuePtr(vHashData), (size_t)RSTRING_LEN(vHashData));

Cleanup:
  /*
   * BIO * pkey_bio = NULL;
   * RSA * rsa_pub_key = NULL;
   * EVP_PKEY * pkey = NULL;
   * EVP_PKEY_CTX * pkey_ctx = NULL;
   * char * pub_key = NULL;
   */
  if (pkey_ctx) EVP_PKEY_CTX_free(pkey_ctx);
  if (pkey) EVP_PKEY_free(pkey);
  if (rsa_pub_key) RSA_free(rsa_pub_key);
  if (pkey_bio) BIO_free(pkey_bio);
  if (pub_key) free(pub_key);

  switch (err) {
    case OK:
      switch (verify_rval) {
        case 1:
          return Qtrue;
        case 0:
          return Qfalse;
        default:
          bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
          rb_raise(rb_cRSAError, "An error occurred during validation.\n%s", ossl_err_strs);
      }
      break;

    case EXTERNAL:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_eRuntimeError, "OpenSSL was in an error state prior to invoking this verification.\n%s", ossl_err_strs);
      break;
    case KEY_OVERFLOW:
      rb_raise(rb_cRSAError, "Your public key is too big. How is that even possible?");
      break;
    case NOMEM:
      rb_raise(rb_const_get_at(rb_mErrno, rb_intern("ENOMEM")), "Insufficient memory to allocate pubkey copy. Woof.");
      break;
    case PUBKEY_PARSE:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Error parsing public key\n%s", ossl_err_strs);
      break;
    case PKEY_INIT:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to initialize PKEY\n%s", ossl_err_strs);
      break;
    case RSA_ASSIGN:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to assign RSA object to PKEY\n%s", ossl_err_strs);
      break;
    case PKEY_CTX_INIT:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to initialize PKEY context.\n%s", ossl_err_strs);
      break;
    case VERIFY_INIT:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to initialize verification process.\n%s", ossl_err_strs);
      break;
    case SET_SIG_MD:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to set signature message digest to SHA1.\n%s", ossl_err_strs);
      break;
    case SET_PADDING:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to set PSS padding.\n%s", ossl_err_strs);
      break;
    case SET_SALTLEN:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_cRSAError, "Failed to set salt length.\n%s", ossl_err_strs);
      break;
    default:
      bind_err_strs(ossl_err_strs, ORPV_MAX_ERRS);
      rb_raise(rb_eRuntimeError, "Something has gone horribly wrong.\n%s", ossl_err_strs);
  }

  return Qnil;
}
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 (OPENSSL_TYPE__FILE_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 (!TINYCLR_SSL_STRCMP(*args,"-outform"))
			{
			if (args[1])
				{
				args++;
				outformat=str2fmt(*args);
				}
			else badarg = 1;
			}
		else if (!TINYCLR_SSL_STRCMP(*args,"-pass"))
			{
			if (!args[1]) goto bad;
			passarg= *(++args);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (TINYCLR_SSL_STRCMP(*args,"-engine") == 0)
			{
			if (!args[1])
				goto bad;
        		e = setup_engine(bio_err, *(++args), 0);
			}
#endif
		else if (!TINYCLR_SSL_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 (!TINYCLR_SSL_STRCMP (*args, "-out"))
			{
			if (args[1])
				{
				args++;
				outfile = *args;
				}
			else badarg = 1;
			}
		else if (TINYCLR_SSL_STRCMP(*args,"-algorithm") == 0)
			{
			if (!args[1])
				goto bad;
			if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
				goto end;
			}
		else if (TINYCLR_SSL_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 (TINYCLR_SSL_STRCMP(*args,"-genparam") == 0)
			{
			if (ctx)
				goto bad;
			do_param = 1;
			}
		else if (TINYCLR_SSL_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 (OPENSSL_TYPE__FILE_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;
	}
예제 #15
0
파일: pkeyutl.c 프로젝트: tiran/openssl
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
                              const char *keyfile, int keyform, int key_type,
                              char *passinarg, int pkey_op, ENGINE *e,
                              const int engine_impl, EVP_PKEY **ppkey)
{
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    ENGINE *impl = NULL;
    char *passin = NULL;
    int rv = -1;
    X509 *x;
    if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
         || (pkey_op == EVP_PKEY_OP_DERIVE))
        && (key_type != KEY_PRIVKEY && kdfalg == NULL)) {
        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;
    }
    switch (key_type) {
    case KEY_PRIVKEY:
        pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key");
        break;

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

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

    case KEY_NONE:
        break;

    }

#ifndef OPENSSL_NO_ENGINE
    if (engine_impl)
        impl = e;
#endif

    if (kdfalg != NULL) {
        int kdfnid = OBJ_sn2nid(kdfalg);

        if (kdfnid == NID_undef) {
            kdfnid = OBJ_ln2nid(kdfalg);
            if (kdfnid == NID_undef) {
                BIO_printf(bio_err, "The given KDF \"%s\" is unknown.\n",
                           kdfalg);
                goto end;
            }
        }
        ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
    } else {
        EC_KEY *eckey = NULL;
        const EC_GROUP *group = NULL;
        int nid;

        if (pkey == NULL)
            goto end;
        /* SM2 needs a special treatment */
        if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
            if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL
                    || (group = EC_KEY_get0_group(eckey)) == NULL
                    || (nid = EC_GROUP_get_curve_name(group)) == 0)
                goto end;
            if (nid == NID_sm2)
                EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
        }
        *pkeysize = EVP_PKEY_size(pkey);
        ctx = EVP_PKEY_CTX_new(pkey, impl);
        if (ppkey != NULL)
            *ppkey = pkey;
        EVP_PKEY_free(pkey);
    }

    if (ctx == NULL)
        goto end;

    switch (pkey_op) {
    case EVP_PKEY_OP_SIGN:
        rv = EVP_PKEY_sign_init(ctx);
        break;

    case EVP_PKEY_OP_VERIFY:
        rv = EVP_PKEY_verify_init(ctx);
        break;

    case EVP_PKEY_OP_VERIFYRECOVER:
        rv = EVP_PKEY_verify_recover_init(ctx);
        break;

    case EVP_PKEY_OP_ENCRYPT:
        rv = EVP_PKEY_encrypt_init(ctx);
        break;

    case EVP_PKEY_OP_DECRYPT:
        rv = EVP_PKEY_decrypt_init(ctx);
        break;

    case EVP_PKEY_OP_DERIVE:
        rv = EVP_PKEY_derive_init(ctx);
        break;
    }

    if (rv <= 0) {
        EVP_PKEY_CTX_free(ctx);
        ctx = NULL;
    }

 end:
    OPENSSL_free(passin);
    return ctx;

}
예제 #16
0
static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len,
		const unsigned char *params, int params_len,
		unsigned char *data, int data_len,
		unsigned char *signat, int signat_len)
{
	EVP_PKEY *pkey;
	EVP_PKEY_CTX *pkey_ctx = NULL;
	EC_POINT *P;
	BIGNUM *X, *Y;
	ASN1_OCTET_STRING *octet;
	const EC_GROUP *group = NULL;
	char paramset[2] = "A";
	int r = -1, ret_vrf = 0;

	pkey = EVP_PKEY_new();
	if (!pkey)
		return CKR_HOST_MEMORY;
	r = EVP_PKEY_set_type(pkey, NID_id_GostR3410_2001);
	if (r == 1) {
		pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
		if (!pkey_ctx) {
			EVP_PKEY_free(pkey);
			return CKR_HOST_MEMORY;
		}
		/* FIXME: fully check params[] */
		if (params_len > 0 && params[params_len - 1] >= 1 &&
				params[params_len - 1] <= 3) {
			paramset[0] += params[params_len - 1] - 1;
			r = EVP_PKEY_CTX_ctrl_str(pkey_ctx, "paramset", paramset);
		}
		else
			r = -1;
		if (r == 1)
			r = EVP_PKEY_paramgen_init(pkey_ctx);
		if (r == 1)
			r = EVP_PKEY_paramgen(pkey_ctx, &pkey);
		if (r == 1 && EVP_PKEY_get0(pkey) != NULL)
			group = EC_KEY_get0_group(EVP_PKEY_get0(pkey));
		r = -1;
		if (group)
			octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey, (long)pubkey_len);
		if (group && octet) {
			reverse(octet->data, octet->length);
			Y = BN_bin2bn(octet->data, octet->length / 2, NULL);
			X = BN_bin2bn((const unsigned char*)octet->data +
					octet->length / 2, octet->length / 2, NULL);
			ASN1_OCTET_STRING_free(octet);
			P = EC_POINT_new(group);
			if (P && X && Y)
				r = EC_POINT_set_affine_coordinates_GFp(group,
						P, X, Y, NULL);
			BN_free(X);
			BN_free(Y);
			if (r == 1 && EVP_PKEY_get0(pkey) && P)
				r = EC_KEY_set_public_key(EVP_PKEY_get0(pkey), P);
			EC_POINT_free(P);
		}
		if (r == 1) {
			r = EVP_PKEY_verify_init(pkey_ctx);
			reverse(data, data_len);
			if (r == 1)
				ret_vrf = EVP_PKEY_verify(pkey_ctx, signat, signat_len,
						data, data_len);
		}
	}
	EVP_PKEY_CTX_free(pkey_ctx);
	EVP_PKEY_free(pkey);
	if (r != 1)
		return CKR_GENERAL_ERROR;
	return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID;
}
예제 #17
0
파일: pkeyutl.c 프로젝트: tiran/openssl
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;
}
예제 #18
0
DWORD
VmDirVerifyRSASignature(
    EVP_PKEY*               pPubKey,
    const EVP_MD*           digestMethod,
    const unsigned char*    pData,
    size_t                  dataSize,
    const unsigned char*    pSignature,
    size_t                  signatureSize,
    PBOOLEAN                pVerified
    )
{
    DWORD   dwError = 0;
    int     retVal = 0;
    unsigned char*  pMd = NULL;
    size_t          mdSize = 0;
    EVP_PKEY_CTX*   pPubKeyCtx = NULL;

    if (!pPubKey || !digestMethod || !pData || !pData || !pVerified)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = VmDirComputeMessageDigest(digestMethod, pData, dataSize, &pMd, &mdSize);
    BAIL_ON_VMDIR_ERROR(dwError);

    pPubKeyCtx = EVP_PKEY_CTX_new(pPubKey, NULL);
    if (!pPubKeyCtx)
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: EVP_PKEY_CTX_new returned NULL",
                __FUNCTION__);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    retVal = EVP_PKEY_verify_init(pPubKeyCtx);
    if (retVal <= 0)
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: EVP_PKEY_verify_init returned %d",
                __FUNCTION__,
                retVal);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    retVal = EVP_PKEY_CTX_set_rsa_padding(pPubKeyCtx, RSA_PKCS1_PADDING);
    if (retVal <= 0)
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: EVP_PKEY_CTX_set_rsa_padding returned %d",
                __FUNCTION__,
                retVal);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    retVal = EVP_PKEY_CTX_set_signature_md(pPubKeyCtx, digestMethod);
    if (retVal <= 0)
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: EVP_PKEY_CTX_set_signature_md returned %d",
                __FUNCTION__,
                retVal);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    retVal = EVP_PKEY_verify(pPubKeyCtx, pSignature, signatureSize, pMd, mdSize);
    if (retVal == 1)
    {
        *pVerified = TRUE;
    }
    else if (retVal == 0)
    {
        *pVerified = FALSE;
    }
    else
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: EVP_PKEY_verify returned %d",
                __FUNCTION__,
                retVal);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pMd);
    EVP_PKEY_CTX_free(pPubKeyCtx);
    return dwError;

error:
    VMDIR_LOG_ERROR(
            VMDIR_LOG_MASK_ALL,
            "%s failed with error (%d)",
            __FUNCTION__,
            dwError);

    goto cleanup;
}
예제 #19
0
static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
                           uint8_t *hash, size_t hashlen, int hash_algo)
{
    int rc, ret;
    EVP_PKEY_CTX *pkey_ctx = NULL;
    struct pgpDigSigRSA_s *sig = pgpsig->data;

    void *padded_sig = NULL;

    struct pgpDigKeyRSA_s *key = pgpkey->data;

    if (!constructRSASigningKey(key)) {
        rc = 1;
        goto done;
    }

    pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL);
    if (!pkey_ctx) {
        rc = 1;
        goto done;
    }

    ret = EVP_PKEY_verify_init(pkey_ctx);
    if (ret < 0) {
        rc = 1;
        goto done;
    }

    ret = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PADDING);
    if (ret < 0) {
        rc = 1;
        goto done;
    }

    ret = EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo));
    if (ret < 0) {
        rc = 1;
        goto done;
    }

    int pkey_len = EVP_PKEY_size(key->evp_pkey);
    padded_sig = xcalloc(1, pkey_len);
    if (!BN_bn2binpad(sig->bn, padded_sig, pkey_len)) {
        rc = 1;
        goto done;
    }

    ret = EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen);
    if (ret == 1)
    {
        /* Success */
        rc = 0;
    }
    else
    {
        /* Failure */
        rc = 1;
    }

done:
    EVP_PKEY_CTX_free(pkey_ctx);
    free(padded_sig);
    return rc;
}
예제 #20
0
int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
	     EVP_PKEY *pkey)
	{
	unsigned char m[EVP_MAX_MD_SIZE];
	unsigned int m_len;
	int i=0,ok=0,v;
	EVP_MD_CTX tmp_ctx;
	EVP_PKEY_CTX *pkctx = NULL;

	*siglen=0;
	EVP_MD_CTX_init(&tmp_ctx);
	if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
		goto err;  
	if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len))
		goto err;
	EVP_MD_CTX_cleanup(&tmp_ctx);

	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
		{
		size_t sltmp = (size_t)EVP_PKEY_size(pkey);
		i = 0;
		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
		if (!pkctx)
			goto err;
		if (EVP_PKEY_sign_init(pkctx) <= 0)
			goto err;
		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
			goto err;
		if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
			goto err;
		*siglen = sltmp;
		i = 1;
		err:
		EVP_PKEY_CTX_free(pkctx);
		return i;
		}

	for (i=0; i<4; i++)
		{
		v=ctx->digest->required_pkey_type[i];
		if (v == 0) break;
		if (pkey->type == v)
			{
			ok=1;
			break;
			}
		}
	if (!ok)
		{
		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
		return(0);
		}

	if (ctx->digest->sign == NULL)
		{
		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
		return(0);
		}
	return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
		pkey->pkey.ptr));
	}
예제 #21
0
// Signing functions
bool OSSLGOST::sign(PrivateKey* privateKey, const ByteString& dataToSign,
		    ByteString& signature, const AsymMech::Type mechanism,
		    const void* param /* = NULL */, const size_t paramLen /* = 0 */)
{
	if (mechanism == AsymMech::GOST)
	{
		// Separate implementation for GOST signing without hash computation

		// Check if the private key is the right type
		if (!privateKey->isOfType(OSSLGOSTPrivateKey::type))
		{
			ERROR_MSG("Invalid key type supplied");

			return false;
		}

		// In case of raw GOST, the length of the input data must be 32 bytes
		if (dataToSign.size() != 32)
		{
			ERROR_MSG("Size of data to sign is not 32 bytes");

			return false;
		}

		// Perform the signature operation
		OSSLGOSTPrivateKey* osslKey = (OSSLGOSTPrivateKey*) privateKey;
		EVP_PKEY* pkey = osslKey->getOSSLKey();
		size_t outLen;

		if (pkey == NULL)
		{
			ERROR_MSG("Could not get the OpenSSL private key");

			return false;
		}

		signature.resize(EVP_PKEY_size(pkey));
		outLen = signature.size();

		EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,NULL);
		if (ctx == NULL)
		{
			ERROR_MSG("EVP_PKEY_CTX_new failed");
			return false;
		}

		if (EVP_PKEY_sign_init(ctx) <= 0)
		{
			ERROR_MSG("EVP_PKEY_sign_init failed");
			EVP_PKEY_CTX_free(ctx);
			return false;
		}

		if (EVP_PKEY_sign(ctx, &signature[0], &outLen, dataToSign.const_byte_str(), dataToSign.size()) <= 0)
		{
			ERROR_MSG("An error occurred while performing a signature");
			EVP_PKEY_CTX_free(ctx);
			return false;
		}

		signature.resize(outLen);
		EVP_PKEY_CTX_free(ctx);

		return true;
	}
	else
	{
		// Call default implementation
		return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
	}
}
예제 #22
0
bool bdoc::X509Cert::verifySignature(int digestMethod, int digestSize,
		std::vector<unsigned char> digest,
		std::vector<unsigned char> signature)
{
	int result = 0;
	EVP_PKEY* key = getPublicKey();

	switch (EVP_PKEY_type(key->type)) {
	case EVP_PKEY_RSA:
	{
		if (digest.size() > static_cast<size_t>(digestSize)) {
			// The digest already has an ASN.1 DigestInfo header.
			break;
		}
		X509_SIG *sig = X509_SIG_new();
		// Prefer set0 to set_md, so we don't have to initialize the
		// digest lookup table with OpenSSL_add_all_digests. None of
		// our supported digests have parameters anyway.
		X509_ALGOR_set0(sig->algor, OBJ_nid2obj(digestMethod), V_ASN1_NULL, NULL);
		ASN1_OCTET_STRING_set(sig->digest, &digest[0], digest.size());

		unsigned char *asn1 = NULL;
		size_t asn1_len = i2d_X509_SIG(sig, &asn1);
		digest = std::vector<unsigned char>(asn1, asn1 + asn1_len);
		X509_SIG_free(sig);
		break;
	}
	case EVP_PKEY_EC:
	{
		ECDSA_SIG *sig = ECDSA_SIG_new();
		// signature is just r and s concatenated, so split them.
		size_t n_len = signature.size() >> 1;
		BN_bin2bn(&signature[0],     n_len, sig->r);
		BN_bin2bn(&signature[n_len], n_len, sig->s);

		unsigned char *asn1 = NULL;
		size_t asn1_len = i2d_ECDSA_SIG(sig, &asn1);
		signature = std::vector<unsigned char>(asn1, asn1 + asn1_len);
		ECDSA_SIG_free(sig);
		break;
	}
	default:
		THROW_STACK_EXCEPTION("Certificate '%s' has an unsupported "
				"public key type, can not verify signature.",
				getSubject().c_str());
	}

	EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(key, NULL);
	if (!ctx) {
		EVP_PKEY_free(key);
		THROW_STACK_EXCEPTION("Creating signature verification "
				"context failed: %s",
				ERR_reason_error_string(ERR_get_error()));
	}

	if (EVP_PKEY_verify_init(ctx) <= 0) {
		EVP_PKEY_CTX_free(ctx);
		EVP_PKEY_free(key);
		THROW_STACK_EXCEPTION("Initializing signature "
				"verification context failed: %s",
				ERR_reason_error_string(ERR_get_error()));
	}
	result = EVP_PKEY_verify(ctx, &signature[0], signature.size(),
			&digest[0], digest.size());
	if (result < 0) {
		EVP_PKEY_CTX_free(ctx);
		EVP_PKEY_free(key);
		THROW_STACK_EXCEPTION("Error during signature verification: %s",
				ERR_reason_error_string(ERR_get_error()));
	}

	EVP_PKEY_CTX_free(ctx);
	EVP_PKEY_free(key);

	return (result == 1);
}
예제 #23
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 ret = 1, rv = -1;
    size_t buf_outlen;

    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_INKEY:
            ctx = init_ctx(&keysize, opt_arg(), keyform, key_type,
                           passinarg, pkey_op, e);
            if (ctx == NULL) {
                BIO_puts(bio_err, "%s: Error initializing context\n");
                ERR_print_errors(bio_err);
                goto opthelp;
            }
            break;
        case OPT_PEERKEY:
            if (!setup_peer(ctx, peerform, opt_arg()))
                goto opthelp;
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PEERFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &peerform))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &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_REV:
            rev = 1;
        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_PKEYOPT:
            if (ctx == NULL) {
                BIO_printf(bio_err,
                           "%s: Must have -inkey before -pkeyopt\n", prog);
                goto opthelp;
            }
            if (pkey_ctrl_string(ctx, opt_arg()) <= 0) {
                BIO_printf(bio_err, "%s: Can't set parameter:\n", prog);
                ERR_print_errors(bio_err);
                goto end;
            }
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (ctx == NULL)
        goto opthelp;

    if (!app_load_modules(NULL))
        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, "rb");
        if (in == NULL)
            goto end;
    }
    out = bio_open_default(outfile, "wb");
    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_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);
    return ret;
}
예제 #24
0
int
genpkey_main(int argc, char **argv)
{
	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 (single_execution) {
		if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	outformat = FORMAT_PEM;

	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);
		}
		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))
				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), 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");
		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);
	}

	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);
	free(pass);

	return ret;
}
예제 #25
0
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(stderr, BIO_NOCLOSE);

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

    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, e);
                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));
        }
#ifndef OPENSSL_NO_ENGINE
        else if (!strcmp(*argv, "-engine")) {
            if (--argc < 1)
                badarg = 1;
            else
                e = setup_engine(bio_err, *(++argv), 0);
        }
#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, "-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;
    }

/* 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(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);
#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");
            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 = 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;
}
예제 #26
0
/* Padding is ignored. We use OAEP by default. Parameter is to support more paddings in the future */
soter_status_t soter_asym_cipher_init(soter_asym_cipher_t* asym_cipher, const void* key, const size_t key_length, soter_asym_cipher_padding_t pad)
{
	EVP_PKEY *pkey;

	if ((!asym_cipher) || (SOTER_ASYM_CIPHER_OAEP != pad))
	{
		return SOTER_INVALID_PARAMETER;
	}

	pkey = EVP_PKEY_new();
	if (!pkey)
	{
		return SOTER_NO_MEMORY;
	}

	/* Only RSA supports asymmetric encryption */
	if (!EVP_PKEY_set_type(pkey, EVP_PKEY_RSA))
	{
		EVP_PKEY_free(pkey);
		return SOTER_FAIL;
	}

	asym_cipher->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
	if (!(asym_cipher->pkey_ctx))
	{
		EVP_PKEY_free(pkey);
		return SOTER_FAIL;
	}
	SOTER_IF_FAIL(soter_asym_cipher_import_key(asym_cipher, key, key_length)==SOTER_SUCCESS, (EVP_PKEY_free(pkey), EVP_PKEY_CTX_free(asym_cipher->pkey_ctx)));
	return SOTER_SUCCESS;
}
예제 #27
0
파일: pmeth_lib.c 프로젝트: zsdev2015/GmSSL
static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
{
    EVP_PKEY_CTX *ret;
    const EVP_PKEY_METHOD *pmeth;
    if (id == -1) {
        if (!pkey || !pkey->ameth)
            return NULL;
        id = pkey->ameth->pkey_id;
    }
#ifndef OPENSSL_NO_ENGINE
    if (pkey && pkey->engine)
        e = pkey->engine;
    /* Try to find an ENGINE which implements this method */
    if (e) {
        if (!ENGINE_init(e)) {
            EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
            return NULL;
        }
    } else
        e = ENGINE_get_pkey_meth_engine(id);

    /*
     * If an ENGINE handled this method look it up. Otherwise use internal
     * tables.
     */

    if (e)
        pmeth = ENGINE_get_pkey_meth(e, id);
    else
#endif
        pmeth = EVP_PKEY_meth_find(id);

    if (pmeth == NULL) {
        EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
        return NULL;
    }

    ret = OPENSSL_zalloc(sizeof(*ret));
    if (ret == NULL) {
#ifndef OPENSSL_NO_ENGINE
        ENGINE_finish(e);
#endif
        EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ret->engine = e;
    ret->pmeth = pmeth;
    ret->operation = EVP_PKEY_OP_UNDEFINED;
    ret->pkey = pkey;
    if (pkey)
        EVP_PKEY_up_ref(pkey);

    if (pmeth->init) {
        if (pmeth->init(ret) <= 0) {
            EVP_PKEY_CTX_free(ret);
            return NULL;
        }
    }

    return ret;
}
예제 #28
0
파일: dgst.c 프로젝트: AlexanderPankiv/node
int dgst_main(int argc, char **argv)
{
    BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
    ENGINE *e = NULL, *impl = NULL;
    EVP_PKEY *sigkey = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
    char *hmac_key = NULL;
    char *mac_name = NULL;
    char *passinarg = NULL, *passin = NULL;
    const EVP_MD *md = NULL, *m;
    const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
    const char *sigfile = NULL, *randfile = NULL;
    OPTION_CHOICE o;
    int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
    int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
    unsigned char *buf = NULL, *sigbuf = NULL;
    int engine_impl = 0;

    prog = opt_progname(argv[0]);
    buf = app_malloc(BUFSIZE, "I/O buffer");
    md = EVP_get_digestbyname(prog);

    prog = opt_init(argc, argv, dgst_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(dgst_options);
            ret = 0;
            goto end;
        case OPT_C:
            separator = 1;
            break;
        case OPT_R:
            separator = 2;
            break;
        case OPT_RAND:
            randfile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGN:
            keyfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_VERIFY:
            keyfile = opt_arg();
            want_pub = do_verify = 1;
            break;
        case OPT_PRVERIFY:
            keyfile = opt_arg();
            do_verify = 1;
            break;
        case OPT_SIGNATURE:
            sigfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_HEX:
            out_bin = 0;
            break;
        case OPT_BINARY:
            out_bin = 1;
            break;
        case OPT_DEBUG:
            debug = 1;
            break;
        case OPT_FIPS_FINGERPRINT:
            hmac_key = "etaonrishdlcupfm";
            break;
        case OPT_HMAC:
            hmac_key = opt_arg();
            break;
        case OPT_MAC:
            mac_name = opt_arg();
            break;
        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_MACOPT:
            if (!macopts)
                macopts = sk_OPENSSL_STRING_new_null();
            if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_DIGEST:
            if (!opt_md(opt_unknown(), &m))
                goto opthelp;
            md = m;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (keyfile != NULL && argc > 1) {
        BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog);
        goto end;
    }

    if (do_verify && !sigfile) {
        BIO_printf(bio_err,
                   "No signature to verify: use the -signature option\n");
        goto end;
    }
    if (engine_impl)
        impl = e;

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

    if (debug) {
        BIO_set_callback(in, BIO_debug_callback);
        /* needed for windows 3.1 */
        BIO_set_callback_arg(in, (char *)bio_err);
    }

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

    if (out_bin == -1) {
        if (keyfile)
            out_bin = 1;
        else
            out_bin = 0;
    }

    if (randfile)
        app_RAND_load_file(randfile, 0);

    out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
    if (out == NULL)
        goto end;

    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        goto end;
    }

    if (keyfile) {
        if (want_pub)
            sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
        else
            sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
        if (!sigkey) {
            /*
             * load_[pub]key() has already printed an appropriate message
             */
            goto end;
        }
    }

    if (mac_name) {
        EVP_PKEY_CTX *mac_ctx = NULL;
        int r = 0;
        if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
            goto mac_end;
        if (macopts) {
            char *macopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
                macopt = sk_OPENSSL_STRING_value(macopts, i);
                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
                    BIO_printf(bio_err,
                               "MAC parameter error \"%s\"\n", macopt);
                    ERR_print_errors(bio_err);
                    goto mac_end;
                }
            }
        }
        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
            BIO_puts(bio_err, "Error generating key\n");
            ERR_print_errors(bio_err);
            goto mac_end;
        }
        r = 1;
 mac_end:
        EVP_PKEY_CTX_free(mac_ctx);
        if (r == 0)
            goto end;
    }

    if (hmac_key) {
        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
                                      (unsigned char *)hmac_key, -1);
        if (!sigkey)
            goto end;
    }

    if (sigkey) {
        EVP_MD_CTX *mctx = NULL;
        EVP_PKEY_CTX *pctx = NULL;
        int r;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (do_verify)
            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
        else
            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
        if (!r) {
            BIO_printf(bio_err, "Error setting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (sigopts) {
            char *sigopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
                    ERR_print_errors(bio_err);
                    goto end;
                }
            }
        }
    }
    /* we use md as a filter, reading from 'in' */
    else {
        EVP_MD_CTX *mctx = NULL;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (md == NULL)
            md = EVP_sha256();
        if (!EVP_DigestInit_ex(mctx, md, impl)) {
            BIO_printf(bio_err, "Error setting digest\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (sigfile && sigkey) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        siglen = EVP_PKEY_size(sigkey);
        sigbuf = app_malloc(siglen, "signature buffer");
        siglen = BIO_read(sigbio, sigbuf, siglen);
        BIO_free(sigbio);
        if (siglen <= 0) {
            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    inp = BIO_push(bmd, in);

    if (md == NULL) {
        EVP_MD_CTX *tctx;
        BIO_get_md_ctx(bmd, &tctx);
        md = EVP_MD_CTX_md(tctx);
    }

    if (argc == 0) {
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                    siglen, NULL, NULL, "stdin");
    } else {
        const char *md_name = NULL, *sig_name = NULL;
        if (!out_bin) {
            if (sigkey) {
                const EVP_PKEY_ASN1_METHOD *ameth;
                ameth = EVP_PKEY_get0_asn1(sigkey);
                if (ameth)
                    EVP_PKEY_asn1_get0_info(NULL, NULL,
                                            NULL, NULL, &sig_name, ameth);
            }
            if (md)
                md_name = EVP_MD_name(md);
        }
        ret = 0;
        for (i = 0; i < argc; i++) {
            int r;
            if (BIO_read_filename(in, argv[i]) <= 0) {
                perror(argv[i]);
                ret++;
                continue;
            } else
                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                          siglen, sig_name, md_name, argv[i]);
            if (r)
                ret = r;
            (void)BIO_reset(bmd);
        }
    }
 end:
    OPENSSL_clear_free(buf, BUFSIZE);
    BIO_free(in);
    OPENSSL_free(passin);
    BIO_free_all(out);
    EVP_PKEY_free(sigkey);
    sk_OPENSSL_STRING_free(sigopts);
    sk_OPENSSL_STRING_free(macopts);
    OPENSSL_free(sigbuf);
    BIO_free(bmd);
    release_engine(e);
    return (ret);
}
예제 #29
0
static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
							CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;
	int ret = 0;
	CMS_EncryptedContentInfo *ec;
	ec = cms->d.envelopedData->encryptedContentInfo;

	if (ktri->pkey == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
			CMS_R_NO_PRIVATE_KEY);
		return 0;
		}

	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
	if (!pctx)
		return 0;

	if (EVP_PKEY_decrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
				ktri->encryptedKey->data,
				ktri->encryptedKey->length) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
							ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
				ktri->encryptedKey->data,
				ktri->encryptedKey->length) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
		goto err;
		}

	ret = 1;

	if (ec->key)
		{
		OPENSSL_cleanse(ec->key, ec->keylen);
		OPENSSL_free(ec->key);
		}

	ec->key = ek;
	ec->keylen = eklen;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (!ret && ek)
		OPENSSL_free(ek);

	return ret;
	}
예제 #30
0
파일: dh.c 프로젝트: KennethL/otp
ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */
    DH *dh_params = NULL;
    int mpint; /* 0 or 4 */

    {
        ERL_NIF_TERM head, tail;
        BIGNUM
            *dh_p = NULL,
            *dh_g = NULL,
            *priv_key_in = NULL;
        unsigned long
            len = 0;

        if (!(get_bn_from_bin(env, argv[0], &priv_key_in)
              || argv[0] == atom_undefined)
            || !enif_get_list_cell(env, argv[1], &head, &tail)
            || !get_bn_from_bin(env, head, &dh_p)
            || !enif_get_list_cell(env, tail, &head, &tail)
            || !get_bn_from_bin(env, head, &dh_g)
            || !enif_is_empty_list(env, tail)
            || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)
            || !enif_get_ulong(env, argv[3], &len)

            /* Load dh_params with values to use by the generator.
               Mem mgmnt transfered from dh_p etc to dh_params */
            || !(dh_params = DH_new())
            || (priv_key_in && !DH_set0_key(dh_params, NULL, priv_key_in))
            || !DH_set0_pqg(dh_params, dh_p, NULL, dh_g)
            ) {
            if (priv_key_in) BN_free(priv_key_in);
            if (dh_p) BN_free(dh_p);
            if (dh_g) BN_free(dh_g);
            if (dh_params) DH_free(dh_params);
            return enif_make_badarg(env);
        }

        if (len) {
            if (len < BN_num_bits(dh_p))
                DH_set_length(dh_params, len);
            else {
                if (priv_key_in) BN_free(priv_key_in);
                if (dh_p) BN_free(dh_p);
                if (dh_g) BN_free(dh_g);
                if (dh_params) DH_free(dh_params);
                return enif_make_badarg(env);
            }
        }
    }

#ifdef HAS_EVP_PKEY_CTX
    {
        EVP_PKEY_CTX *ctx;
        EVP_PKEY *dhkey, *params;
        int success;

        params = EVP_PKEY_new();
        success = EVP_PKEY_set1_DH(params, dh_params);   /* set the key referenced by params to dh_params... */
        DH_free(dh_params);                              /* ...dh_params (and params) must be freed */
        if (!success) return atom_error;

        ctx = EVP_PKEY_CTX_new(params, NULL);
        EVP_PKEY_free(params);
        if (!ctx) {
            return atom_error;
        }

        if (!EVP_PKEY_keygen_init(ctx)) {
            /* EVP_PKEY_CTX_free(ctx); */
            return atom_error;
        }

        dhkey = EVP_PKEY_new();
        if (!EVP_PKEY_keygen(ctx, &dhkey)) {         /* "performs a key generation operation, the ... */
                                                     /*... generated key is written to ppkey." (=last arg) */
             /* EVP_PKEY_CTX_free(ctx); */
             /* EVP_PKEY_free(dhkey); */
             return atom_error;
        }

        dh_params = EVP_PKEY_get1_DH(dhkey); /* return the referenced key. dh_params and dhkey must be freed */
        EVP_PKEY_free(dhkey);
        if (!dh_params) {
            /* EVP_PKEY_CTX_free(ctx); */
            return atom_error;
        }
        EVP_PKEY_CTX_free(ctx);
    }
#else
    if (!DH_generate_key(dh_params)) return atom_error;
#endif
    {
        unsigned char *pub_ptr, *prv_ptr;
        int pub_len, prv_len;
        ERL_NIF_TERM ret_pub, ret_prv;
        const BIGNUM *pub_key_gen, *priv_key_gen;

        DH_get0_key(dh_params,
                    &pub_key_gen, &priv_key_gen); /* Get pub_key_gen and priv_key_gen.
                                                     "The values point to the internal representation of
                                                     the public key and private key values. This memory
                                                     should not be freed directly." says man */
        pub_len = BN_num_bytes(pub_key_gen);
        prv_len = BN_num_bytes(priv_key_gen);
        pub_ptr = enif_make_new_binary(env, pub_len+mpint, &ret_pub);
        prv_ptr = enif_make_new_binary(env, prv_len+mpint, &ret_prv);
        if (mpint) {
            put_int32(pub_ptr, pub_len); pub_ptr += 4;
            put_int32(prv_ptr, prv_len); prv_ptr += 4;
        }
        BN_bn2bin(pub_key_gen, pub_ptr);
        BN_bn2bin(priv_key_gen, prv_ptr);
        ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len);
        ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len);

        DH_free(dh_params);

        return enif_make_tuple2(env, ret_pub, ret_prv);
    }
}