Exemple #1
0
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
                          int is_verify) {
  if (ctx->pctx == NULL) {
    ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
  }
  if (ctx->pctx == NULL) {
    return 0;
  }
  ctx->pctx_ops = &md_pctx_ops;

  if (type == NULL) {
    type = EVP_sha1();
  }

  if (type == NULL) {
    OPENSSL_PUT_ERROR(EVP, do_sigver_init, EVP_R_NO_DEFAULT_DIGEST);
    return 0;
  }

  if (is_verify) {
    if (ctx->pctx->pmeth->verifyctx_init) {
      if (!ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx)) {
        return 0;
      }
      ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
    } else if (!EVP_PKEY_verify_init(ctx->pctx)) {
      return 0;
    }
  } else {
    if (ctx->pctx->pmeth->signctx_init) {
      if (!ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx)) {
        return 0;
      }
      ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
    } else if (!EVP_PKEY_sign_init(ctx->pctx)) {
      return 0;
    }
  }
  if (!EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) {
    return 0;
  }
  if (pctx) {
    *pctx = ctx->pctx;
  }
  if (!EVP_DigestInit_ex(ctx, type, e)) {
    return 0;
  }
  return 1;
}
Exemple #2
0
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
                          int ver)
{
    if (ctx->pctx == NULL)
        ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
    if (ctx->pctx == NULL)
        return 0;

    if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {

        if (type == NULL) {
            int def_nid;
            if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
                type = EVP_get_digestbynid(def_nid);
        }

        if (type == NULL) {
            EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
            return 0;
        }
    }
    if (ver) {
        if (ctx->pctx->pmeth->verifyctx_init) {
            if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
                return 0;
            ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
        } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
            return 0;
    } else {
        if (ctx->pctx->pmeth->signctx_init) {
            if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) {
                return 0;
            }
            ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
        } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
            return 0;
    }
    if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
        return 0;
    if (pctx)
        *pctx = ctx->pctx;
    if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
        return 1;
    if (!EVP_DigestInit_ex(ctx, type, e))
        return 0;
    return 1;
}
Exemple #3
0
int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                    unsigned int siglen, EVP_PKEY *pkey)
{
    unsigned char m[EVP_MAX_MD_SIZE];
    unsigned int m_len = 0;
    int i = 0;
    EVP_PKEY_CTX *pkctx = NULL;

    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
        if (!EVP_DigestFinal_ex(ctx, m, &m_len))
            goto err;
    } else {
        int rv = 0;
        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
        if (tmp_ctx == NULL) {
            EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
        if (rv)
            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
        EVP_MD_CTX_free(tmp_ctx);
        if (!rv)
            return 0;
    }

    i = -1;
    pkctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (pkctx == NULL)
        goto err;
    if (EVP_PKEY_verify_init(pkctx) <= 0)
        goto err;
    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
        goto err;
    i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
 err:
    EVP_PKEY_CTX_free(pkctx);
    return i;
}
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
                          int is_verify) {
  if (ctx->pctx == NULL) {
    ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
  }
  if (ctx->pctx == NULL) {
    return 0;
  }
  ctx->pctx_ops = &md_pctx_ops;

  if (type == NULL) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST);
    return 0;
  }

  if (is_verify) {
    if (!EVP_PKEY_verify_init(ctx->pctx)) {
      return 0;
    }
  } else {
    if (!EVP_PKEY_sign_init(ctx->pctx)) {
      return 0;
    }
  }
  if (!EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) {
    return 0;
  }
  if (pctx) {
    *pctx = ctx->pctx;
  }
  if (!EVP_DigestInit_ex(ctx, type, e)) {
    return 0;
  }
  return 1;
}
Exemple #5
0
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;

}
Exemple #6
0
int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
	     unsigned int siglen, EVP_PKEY *pkey)
	{
	unsigned char m[EVP_MAX_MD_SIZE];
	unsigned int m_len;
	int i = 0,ok = 0,v;
	EVP_PKEY_CTX *pkctx = NULL;

	if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
		{
		if (!EVP_DigestFinal_ex(ctx, m, &m_len))
			goto err;
		}
	else
		{
		int rv;
		EVP_MD_CTX tmp_ctx;
		EVP_MD_CTX_init(&tmp_ctx);
		rv = EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
		if (rv)
			rv = EVP_DigestFinal_ex(&tmp_ctx, m, &m_len);
		EVP_MD_CTX_cleanup(&tmp_ctx);
		if (!rv)
			return 0;
		}

	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
		{
		i = -1;
		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
		if (!pkctx)
			goto err;
		if (EVP_PKEY_verify_init(pkctx) <= 0)
			goto err;
		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
			goto err;
		i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
		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_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
		return(-1);
		}
        if (ctx->digest->verify == NULL)
                {
		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
		return(0);
		}

	return(ctx->digest->verify(ctx->digest->type,m,m_len,
		sigbuf,siglen,pkey->pkey.ptr));
	}
Exemple #7
0
int main()
{
	int ret = -1;
	int verbose = 0;
	BIO *out = NULL;

	int id = EVP_PKEY_SM2;
	const EVP_MD *md = EVP_sm3();
	ENGINE *engine = NULL;

	EVP_PKEY_CTX *pkctx = NULL;
	EVP_PKEY *pkey = NULL;
	EVP_MD_CTX *mdctx = NULL;
	EVP_CIPHER_CTX *cpctx = NULL;

	unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world";
	size_t dgstlen = 32;
	unsigned char sig[256];
	size_t siglen = sizeof(sig);

	unsigned char msg[] = "hello world this is the message";
	size_t msglen = sizeof(msg);
	unsigned char cbuf[512];
	size_t cbuflen = sizeof(cbuf);
	unsigned char mbuf[512];
	size_t mbuflen = sizeof(mbuf);

	int len;
	unsigned int ulen;

	ERR_load_crypto_strings();

	out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen(pkctx, &pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	EVP_PKEY_CTX_free(pkctx);

	if (0) {
		EVP_PKEY_print_public(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
		EVP_PKEY_print_private(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
	}

	if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	/* EVP_PKEY_sign() */

	if (!EVP_PKEY_sign_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(sig, sizeof(sig));
	siglen = sizeof(sig);
	dgstlen = 32;

	if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_verify_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("signature verification success!\n");
	}

	/* EVP_PKEY_encrypt() */

	if (!EVP_PKEY_encrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	cbuflen = sizeof(cbuf);
	if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("ciphertext (%zu bytes) = ", cbuflen);
		for (i = 0; i < cbuflen; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_decrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(mbuf, sizeof(mbuf));
	mbuflen = sizeof(mbuf);
	if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}


	/* EVP_PKEY_encrypt_old */


	if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		int i;
		printf("ciphertext (%d bytes) = ", len);
		for (i = 0; i < len; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	bzero(mbuf, sizeof(mbuf));
	if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}

	if (!(mdctx = EVP_MD_CTX_create())) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	
	/* EVP_SignInit_ex/Update/Final_ex */

	if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}
	siglen = ulen;

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_VerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_DigestSignInit/Update/Final() */
	// FIXME: return values might be different, not just 1 or 0
	if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	siglen = sizeof(sig);
	if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	pkctx = NULL;	
	if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */
	/*
	EVP_PKEY *pk[NUM_PKEYS] = {0};
	unsigned char iv[16];
	unsigned char ek[NUM_PKEYS][256];
	int eklen[NUM_PKEYS];

	RAND_pseudo_bytes(iv, sizeof(iv));

	int i;
	for (i = 0; i < NUM_PKEYS; i++) {
	}

	if (!(cpctx = EVP_CIPHER_CTX_new())) {
		goto end;
	}

	if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) {
		goto end;
	}

	if (!EVP_SealUpdate(cpctx, msg, msglen)) {
		goto end;
	}

	if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) {
		goto end;
	}
	*/

	printf("test success!\n");
	ret = 1;
end:
	ERR_print_errors_fp(stderr);
	return ret;
}
Exemple #8
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;
	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;
}
Exemple #9
0
/*
 * verify EC signature on JWT
 */
static apr_byte_t apr_jws_verify_ec(apr_pool_t *pool, apr_jwt_t *jwt,
                                    apr_jwk_t *jwk, apr_jwt_error_t *err) {

    int nid = apr_jws_ec_alg_to_curve(jwt->header.alg);
    if (nid == -1) {
        apr_jwt_error(err,
                      "no OpenSSL Elliptic Curve identifier found for algorithm \"%s\"",
                      jwt->header.alg);
        return FALSE;
    }

    EC_GROUP *curve = EC_GROUP_new_by_curve_name(nid);
    if (curve == NULL) {
        apr_jwt_error(err,
                      "no OpenSSL Elliptic Curve found for algorithm \"%s\"",
                      jwt->header.alg);
        return FALSE;
    }

    apr_byte_t rc = FALSE;

    /* get the OpenSSL digest function */
    const EVP_MD *digest = NULL;
    if ((digest = apr_jws_crypto_alg_to_evp(pool, jwt->header.alg, err)) == NULL)
        return FALSE;

    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);

    EC_KEY * pubkey = EC_KEY_new();
    EC_KEY_set_group(pubkey, curve);

    BIGNUM * x = BN_new();
    BIGNUM * y = BN_new();

    BN_bin2bn(jwk->key.ec->x, jwk->key.ec->x_len, x);
    BN_bin2bn(jwk->key.ec->y, jwk->key.ec->y_len, y);

    if (!EC_KEY_set_public_key_affine_coordinates(pubkey, x, y)) {
        apr_jwt_error_openssl(err, "EC_KEY_set_public_key_affine_coordinates");
        return FALSE;
    }

    EVP_PKEY* pEcKey = EVP_PKEY_new();
    if (!EVP_PKEY_assign_EC_KEY(pEcKey, pubkey)) {
        pEcKey = NULL;
        apr_jwt_error_openssl(err, "EVP_PKEY_assign_EC_KEY");
        goto end;
    }

    ctx.pctx = EVP_PKEY_CTX_new(pEcKey, NULL);

    if (!EVP_PKEY_verify_init(ctx.pctx)) {
        apr_jwt_error_openssl(err, "EVP_PKEY_verify_init");
        goto end;
    }
    if (!EVP_VerifyInit_ex(&ctx, digest, NULL)) {
        apr_jwt_error_openssl(err, "EVP_VerifyInit_ex");
        goto end;
    }
    if (!EVP_VerifyUpdate(&ctx, jwt->message, strlen(jwt->message))) {
        apr_jwt_error_openssl(err, "EVP_VerifyUpdate");
        goto end;
    }
    if (!EVP_VerifyFinal(&ctx, (const unsigned char *) jwt->signature.bytes,
                         jwt->signature.length, pEcKey)) {
        apr_jwt_error_openssl(err, "wrong key? EVP_VerifyFinal");
        goto end;
    }

    rc = TRUE;

end:

    if (pEcKey) {
        EVP_PKEY_free(pEcKey);
    } else if (pubkey) {
        EC_KEY_free(pubkey);
    }
    EVP_MD_CTX_cleanup(&ctx);

    return rc;
}
Exemple #10
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;
}
Exemple #11
0
int
EAC_verify(int protocol, EVP_PKEY *key,    const BUF_MEM *signature,
        const BUF_MEM *data)
{
    BUF_MEM *verification_data = NULL, *signature_to_verify = NULL;
    EVP_PKEY_CTX *tmp_key_ctx = NULL;
    int ret = -1;
    const EVP_MD *md = eac_oid2md(protocol);
    int type;

    check((key && signature), "Invalid arguments");

    tmp_key_ctx = EVP_PKEY_CTX_new(key, NULL);
    if (!tmp_key_ctx || !md
               || EVP_PKEY_verify_init(tmp_key_ctx) <= 0
            || EVP_PKEY_CTX_set_signature_md(tmp_key_ctx, md) <= 0)
        goto err;


    type = EVP_PKEY_base_id(key);
    if (       protocol == NID_id_TA_ECDSA_SHA_1
            || protocol == NID_id_TA_ECDSA_SHA_224
            || protocol == NID_id_TA_ECDSA_SHA_256
            || protocol == NID_id_TA_ECDSA_SHA_384
            || protocol == NID_id_TA_ECDSA_SHA_512) {
        if (!(type == EVP_PKEY_EC))
            goto err;

        /* EAC signatures are always in plain signature format for EC curves but
         * OpenSSL only creates X.509 format. Therefore we need to convert between
         * these formats. */
        signature_to_verify = convert_from_plain_sig(signature);
        if (!signature_to_verify)
            goto err;

    } else if (protocol == NID_id_TA_RSA_v1_5_SHA_1
            || protocol == NID_id_TA_RSA_v1_5_SHA_256
            || protocol == NID_id_TA_RSA_v1_5_SHA_512) {
        if (!(type == EVP_PKEY_RSA))
            goto err;

        signature_to_verify = BUF_MEM_create_init(signature->data,
                signature->length);
        if (!EVP_PKEY_CTX_set_rsa_padding(tmp_key_ctx, RSA_PKCS1_PADDING)
                || !signature_to_verify)
            goto err;

    } else if (protocol == NID_id_TA_RSA_PSS_SHA_1
            || protocol == NID_id_TA_RSA_PSS_SHA_256
            || protocol == NID_id_TA_RSA_PSS_SHA_512) {
        if (!(type == EVP_PKEY_RSA))
            goto err;

        signature_to_verify = BUF_MEM_create_init(signature->data, signature->length);
        if (!EVP_PKEY_CTX_set_rsa_padding(tmp_key_ctx, RSA_PKCS1_PSS_PADDING)
                || !signature_to_verify)
            goto err;

    } else {
        goto err;
    }

    /* EVP_PKEY_sign doesn't perform hashing (despite EVP_PKEY_CTX_set_signature_md).
     * Therefore we need to compute the hash ourself. */
    verification_data = hash(md, NULL, NULL, data);
    if (!verification_data)
        goto err;

    /* Actual signature verification */
    ret = EVP_PKEY_verify(tmp_key_ctx, (unsigned char*) signature_to_verify->data,
            signature_to_verify->length, (unsigned char*) verification_data->data,
            verification_data->length);

err:
    if (verification_data)
        BUF_MEM_free(verification_data);
    if (signature_to_verify)
        BUF_MEM_free(signature_to_verify);
    if (tmp_key_ctx)
        EVP_PKEY_CTX_free(tmp_key_ctx);

    return ret;
}
Exemple #12
0
static EVP_PKEY_CTX *
init_ctx(int *pkeysize,
    char *keyfile, int keyform, int key_type,
    char *passargin, int pkey_op)
{
	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, "Private Key");
		break;

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

	case KEY_CERT:
		x = load_cert(bio_err, keyfile, keyform,
		    NULL, "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, NULL);

	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:

	free(passin);

	return ctx;


}
Exemple #13
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);
}
Exemple #14
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;
}
Exemple #15
0
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;
}
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;
}
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;
}
Exemple #18
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 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 *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) {
        int kdfnid = OBJ_sn2nid(kdfalg);
        if (kdfnid == NID_undef)
            goto end;
        ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
    } else {
        if (pkey == NULL)
            goto end;
        *pkeysize = EVP_PKEY_size(pkey);
        ctx = EVP_PKEY_CTX_new(pkey, impl);
        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;

}