コード例 #1
1
bool
validateHelper (
    RSA* key,
    Slice message,
    Slice signature)
{
    int const keySize = RSA_size(key);
    if (!checkModulusLength (keySize))
        return false;

    Buffer buf;

    auto ret = RSA_public_decrypt(
        keySize,
        signature.data(),
        buf.alloc (keySize),
        key,
        RSA_NO_PADDING);

    if (ret == -1)
        return false;

    sha256_hasher h;
    h (message.data(), message.size());
    auto digest = static_cast<sha256_hasher::result_type>(h);

    return RSA_verify_PKCS1_PSS(key, digest.data(), EVP_sha256(), buf.data(), -1) == 1;
}
コード例 #2
1
//Hardcoding this test code for PSS-SHA1
void RsaPssVerification(unsigned int uKeySize, const unsigned char* pMsg, const unsigned char* pSign,
                       unsigned int E, const unsigned char* pN, const unsigned char* pD)
{
    RSA* pRsaKey = NULL;
    const unsigned char* pDigest = NULL;
    size_t uDigestLen = 20;
    unsigned char EM[512];
    unsigned char signature[512];
    unsigned int uLen = 0;
    int status = 0;

    // Generate an RSA key pair
    pRsaKey = GetRsaKey(E, pN, pD);
    if (pRsaKey) {
        //Use the already hashed input message and compute the PSS padded data with max salt size
        pDigest = pMsg;
        printbin("HASH", pDigest, 20);
        status = RSA_padding_add_PKCS1_PSS(pRsaKey, EM, pDigest, EVP_sha1(), -2);
        printbin("EM", EM, uKeySize);
        if (status == 1)  {
            //Now do Rsa Signature (RSA private encrypt)
            status = RSA_private_encrypt(uKeySize, EM, signature, pRsaKey, RSA_NO_PADDING);
            printbin("Sign", signature, uKeySize);
            if (status != -1) {
                //Now its time to verify the signature using RSA public decryption
                //We could directly use signature, but we are here to verify the signature generated by HW KM1
                uLen = hex2bin(signature, pSign);
                //assert(uLen == uKeySize)
                printbin("Sign", signature, uLen);
                status = RSA_public_decrypt(uKeySize, signature, EM, pRsaKey, RSA_NO_PADDING);
                printbin("EM", EM, uKeySize);
                if (status != -1) {
                    //Verify the data against the message with expecting max salt length from ssignature
                    status = RSA_verify_PKCS1_PSS(pRsaKey, pDigest, EVP_sha1(), EM, -2);
                    if (status == 1) {
                        printf("GREAT: Signature verification successful\n");
                    } else {
                        printf("RSA_verify_PKCS1_PSS failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
                    }
                } else {
                    printf("RSA_public_decrypt failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
                }
            } else {
                printf("RSA_private_encrypt failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
            }
        } else {
            printf("RSA_padding_add_PKCS1_PSS failed with error %s\n", ERR_error_string(ERR_get_error(), NULL));
        }
    }

    if (pRsaKey) {
        RSA_free(pRsaKey);
    }
}
コード例 #3
1
static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
					const unsigned char *sig, size_t siglen,
					const unsigned char *tbs, size_t tbslen)
	{
	RSA_PKEY_CTX *rctx = (RSA_PKEY_CTX*)ctx->data;
	RSA *rsa = ctx->pkey->pkey.rsa;
	size_t rslen;
	if (rctx->md)
		{
		if (rctx->pad_mode == RSA_PKCS1_PADDING)
			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
					sig, siglen, rsa);
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
					sig, siglen) <= 0)
				return 0;
			}
		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
			{
			int ret;
			if (!setup_tbuf(rctx, ctx))
				return -1;
			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
							rsa, RSA_NO_PADDING);
			if (ret <= 0)
				return 0;
			ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
						rctx->tbuf, rctx->saltlen);
			if (ret <= 0)
				return 0;
			return 1;
			}
		else
			return -1;
		}
	else
		{
		if (!setup_tbuf(rctx, ctx))
			return -1;
		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
						rsa, rctx->pad_mode);
		if (rslen == 0)
			return 0;
		}

	if ((rslen != tbslen) || TINYCLR_SSL_MEMCMP(tbs, rctx->tbuf, rslen))
		return 0;

	return 1;
			
	}
コード例 #4
1
ファイル: rsa_key.cpp プロジェクト: Cyarix/freelan
		void rsa_key::verify_PKCS1_PSS(const void* digest, size_t digest_len, const void* buf, size_t /*buf_len*/, hash::message_digest_algorithm algorithm, int salt_len) const
		{
			assert(digest_len >= algorithm.result_size());

			if (digest_len < algorithm.result_size())
			{
				throw std::invalid_argument("digest_len");
			}

			//TODO: Use buf_len

			throw_error_if_not(RSA_verify_PKCS1_PSS(ptr().get(), static_cast<const unsigned char*>(digest), algorithm.raw(), static_cast<const unsigned char*>(buf), salt_len) != 0);
		}
コード例 #5
1
ファイル: apr_jws.c プロジェクト: azenk/mod_auth_openidc
/*
 * verify HMAC signature on JWT
 */
static apr_byte_t apr_jws_verify_rsa(apr_pool_t *pool, apr_jwt_t *jwt,
                                     apr_jwk_t *jwk, apr_jwt_error_t *err) {

    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);

    RSA * pubkey = RSA_new();

    BIGNUM * modulus = BN_new();
    BIGNUM * exponent = BN_new();

    BN_bin2bn(jwk->key.rsa->modulus, jwk->key.rsa->modulus_len, modulus);
    BN_bin2bn(jwk->key.rsa->exponent, jwk->key.rsa->exponent_len, exponent);

    pubkey->n = modulus;
    pubkey->e = exponent;

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

    if (apr_jws_signature_starts_with(pool, jwt->header.alg, "PS") == TRUE) {

        int status = 0;
        unsigned char *pDecrypted = apr_pcalloc(pool, jwt->signature.length);
        status = RSA_public_decrypt(jwt->signature.length, jwt->signature.bytes,
                                    pDecrypted, pubkey, RSA_NO_PADDING);
        if (status == -1) {
            apr_jwt_error_openssl(err, "RSA_public_decrypt");
            goto end;
        }

        unsigned char *pDigest = apr_pcalloc(pool, RSA_size(pubkey));
        unsigned int uDigestLen = RSA_size(pubkey);

        if (!EVP_DigestInit(&ctx, digest)) {
            apr_jwt_error_openssl(err, "EVP_DigestInit");
            goto end;
        }
        if (!EVP_DigestUpdate(&ctx, jwt->message, strlen(jwt->message))) {
            apr_jwt_error_openssl(err, "EVP_DigestUpdate");
            goto end;
        }
        if (!EVP_DigestFinal(&ctx, pDigest, &uDigestLen)) {
            apr_jwt_error_openssl(err, "wrong key? EVP_DigestFinal");
            goto end;
        }

        /* verify the data */
        status = RSA_verify_PKCS1_PSS(pubkey, pDigest, digest, pDecrypted,
                                      -2 /* salt length recovered from signature*/);
        if (status != 1) {
            apr_jwt_error_openssl(err, "RSA_verify_PKCS1_PSS");
            goto end;
        }

        rc = TRUE;

    } else if (apr_jws_signature_starts_with(pool, jwt->header.alg,
               "RS") == TRUE) {

        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, pRsaKey)) {
            apr_jwt_error_openssl(err, "wrong key? EVP_VerifyFinal");
            goto end;
        }

        rc = TRUE;

    }

end:

    if (pRsaKey) {
        EVP_PKEY_free(pRsaKey);
    } else if (pubkey) {
        RSA_free(pubkey);
    }
    EVP_MD_CTX_cleanup(&ctx);

    return rc;
}
コード例 #6
1
ファイル: jws.c プロジェクト: cisco/cjose
static bool _cjose_jws_verify_sig_ps(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;
    uint8_t *em = NULL;
    size_t em_len = 0;

    // ensure jwk is RSA
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // build digest using SHA-256/384/512 digest algorithm
    const EVP_MD *digest_alg = NULL;
    if (strcmp(alg, CJOSE_HDR_ALG_PS256) == 0)
        digest_alg = EVP_sha256();
    else if (strcmp(alg, CJOSE_HDR_ALG_PS384) == 0)
        digest_alg = EVP_sha384();
    else if (strcmp(alg, CJOSE_HDR_ALG_PS512) == 0)
        digest_alg = EVP_sha512();

    if (NULL == digest_alg)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // allocate buffer for encoded message
    em_len = RSA_size((RSA *)jwk->keydata);
    em = (uint8_t *)cjose_get_alloc()(em_len);
    if (NULL == em)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // decrypt signature
    if (RSA_public_decrypt(jws->sig_len, jws->sig, em, (RSA *)jwk->keydata, RSA_NO_PADDING) != em_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // verify decrypted signature data against PSS encoded digest
    if (RSA_verify_PKCS1_PSS((RSA *)jwk->keydata, jws->dig, digest_alg, em, -1) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_ps_cleanup:
    cjose_get_dealloc()(em);

    return retval;
}
コード例 #7
1
ファイル: OSSLRSA.cpp プロジェクト: bluelikeme/SoftHSMv2
bool OSSLRSA::verifyFinal(const ByteString& signature)
{
	// Save necessary state before calling super class verifyFinal
	OSSLRSAPublicKey* pk = (OSSLRSAPublicKey*) currentPublicKey;
	AsymMech::Type mechanism = currentMechanism;

	if (!AsymmetricAlgorithm::verifyFinal(signature))
	{
		return false;
	}

	ByteString firstHash, secondHash;

	bool bFirstResult = pCurrentHash->hashFinal(firstHash);
	bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;

	delete pCurrentHash;
	pCurrentHash = NULL;

	if (pSecondHash != NULL)
	{
		delete pSecondHash;

		pSecondHash = NULL;
	}

	if (!bFirstResult || !bSecondResult)
	{
		return false;
	}

	ByteString digest = firstHash + secondHash;

	// Determine the signature NID type
	int type = 0;
	bool isPSS = false;
	const EVP_MD* hash = NULL;

	switch (mechanism)
	{
		case AsymMech::RSA_MD5_PKCS:
			type = NID_md5;
			break;
		case AsymMech::RSA_SHA1_PKCS:
			type = NID_sha1;
			break;
		case AsymMech::RSA_SHA224_PKCS:
			type = NID_sha224;
			break;
		case AsymMech::RSA_SHA256_PKCS:
			type = NID_sha256;
			break;
		case AsymMech::RSA_SHA384_PKCS:
			type = NID_sha384;
			break;
		case AsymMech::RSA_SHA512_PKCS:
			type = NID_sha512;
			break;
		case AsymMech::RSA_SHA1_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha1();
			break;
		case AsymMech::RSA_SHA224_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha224();
			break;
		case AsymMech::RSA_SHA256_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha256();
			break;
		case AsymMech::RSA_SHA384_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha384();
			break;
		case AsymMech::RSA_SHA512_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha512();
			break;
		case AsymMech::RSA_SSL:
			type = NID_md5_sha1;
			break;
		default:
			break;
	}

	// Perform the verify operation
	bool rv;

	if (isPSS)
	{
		ByteString plain;
		plain.resize(pk->getN().size());
		int result = RSA_public_decrypt(signature.size(),
						(unsigned char*) signature.const_byte_str(),
						&plain[0],
						pk->getOSSLKey(),
						RSA_NO_PADDING);
		if (result < 0)
		{
			rv = false;
			ERROR_MSG("RSA public decrypt failed (0x%08X)", ERR_get_error());
		}
		else
		{
			plain.resize(result);
			result = RSA_verify_PKCS1_PSS(pk->getOSSLKey(), &digest[0],
						      hash, &plain[0], sLen);
			if (result == 1)
			{
				rv = true;
			}
			else
			{
				rv = false;
				ERROR_MSG("RSA PSS verify failed (0x%08X)", ERR_get_error());
			}
		}
	}
	else
	{
		rv = (RSA_verify(type, &digest[0], digest.size(), (unsigned char*) signature.const_byte_str(), signature.size(), pk->getOSSLKey()) == 1);

		if (!rv) ERROR_MSG("RSA verify failed (0x%08X)", ERR_get_error());
	}

	return rv;
}
コード例 #8
1
static int fips_rsa_verify(int dtype,
                           const unsigned char *x, unsigned int y,
                           unsigned char *sigbuf, unsigned int siglen,
                           EVP_MD_SVCTX * sv)
{
    int i, ret = 0;
    unsigned int dlen, diglen;
    int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
    int rsa_pad_mode = 0;
    unsigned char *s;
    const unsigned char *der;
    unsigned char dig[EVP_MAX_MD_SIZE];
    RSA *rsa = sv->key;

    if (siglen != (unsigned int)RSA_size(sv->key)) {
        RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
        return (0);
    }

    EVP_DigestFinal_ex(sv->mctx, dig, &diglen);

    if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) {
        return rsa->meth->rsa_verify(dtype, dig, diglen, sigbuf, siglen, rsa);
    }

    s = OPENSSL_malloc((unsigned int)siglen);
    if (s == NULL) {
        RSAerr(RSA_F_FIPS_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
        rsa_pad_mode = RSA_X931_PADDING;
    else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
        rsa_pad_mode = RSA_PKCS1_PADDING;
    else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
        rsa_pad_mode = RSA_NO_PADDING;

    /* NB: call underlying method directly to avoid FIPS blocking */
    i = rsa->meth->rsa_pub_dec((int)siglen, sigbuf, s, rsa, rsa_pad_mode);

    if (i <= 0)
        goto err;

    if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) {
        int hash_id;
        if (i != (int)(diglen + 1)) {
            RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }
        hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
        if (hash_id == -1) {
            RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);
            goto err;
        }
        if (s[diglen] != (unsigned char)hash_id) {
            RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }
        if (memcmp(s, dig, diglen)) {
            RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }
        ret = 1;
    } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) {

        der = fips_digestinfo_encoding(dtype, &dlen);

        if (!der) {
            RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);
            return (0);
        }

        /*
         * Compare, DigestInfo length, DigestInfo header and finally digest
         * value itself
         */

        /* If length mismatch try alternate encoding */
        if (i != (int)(dlen + diglen))
            der = fips_digestinfo_nn_encoding(dtype, &dlen);

        if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
            || memcmp(s + dlen, dig, diglen)) {
            RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }
        ret = 1;

    } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) {
        int saltlen;
        saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
        if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
            saltlen = -1;
        else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
            saltlen = -2;
        ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx),
                                   s, saltlen);
        if (ret < 0)
            ret = 0;
    }
 err:
    if (s != NULL) {
        OPENSSL_cleanse(s, siglen);
        OPENSSL_free(s);
    }
    return (ret);
}