Beispiel #1
0
static void *
bench_openssl_rsa_init (unsigned size)
{
  struct openssl_rsa_ctx *ctx = make_openssl_rsa_ctx (size);
  RSA_blinding_off(ctx->key);
  return ctx;
}
Beispiel #2
0
int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
{
    int ret=0;

    if (rsa->blinding != NULL)
        RSA_blinding_off(rsa);

    rsa->blinding = RSA_setup_blinding(rsa, ctx);
    if (rsa->blinding == NULL)
        goto err;

    rsa->flags |= RSA_FLAG_BLINDING;
    rsa->flags &= ~RSA_FLAG_NO_BLINDING;
    ret=1;
err:
    return(ret);
}
static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD *ui_method,
        void *callback_data) {
    ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);

    Keystore_Reply reply;
    if (keystore_cmd(CommandCodes[GET_PUBKEY], &reply, 1, strlen(key_id), key_id) != NO_ERROR) {
        ALOGV("Cannot get public key for %s", key_id);
        return NULL;
    }

    const unsigned char* tmp = reinterpret_cast<const unsigned char*>(reply.get());
    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, reply.length()));
    if (pkey.get() == NULL) {
        ALOGW("Cannot convert pubkey");
        return NULL;
    }

    switch (EVP_PKEY_type(pkey->type)) {
    case EVP_PKEY_RSA: {
        Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
        if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) {
            ALOGW("Could not set ex_data for loaded RSA key");
            return NULL;
        }

        RSA_set_method(rsa.get(), &keystore_rsa_meth);
        RSA_blinding_off(rsa.get());

        /*
         * This should probably be an OpenSSL API, but EVP_PKEY_free calls
         * ENGINE_finish(), so we need to call ENGINE_init() here.
         */
        ENGINE_init(e);
        rsa->engine = e;
        rsa->flags |= RSA_FLAG_EXT_PKEY;

        break;
    }
    default:
        ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
        return NULL;
    }

    return pkey.release();
}
/* reusable init */
void RSASigner::signerInit(
	const Context 	&context,
	bool			isSigning)
{
	StLock<Mutex> _(gMutex());

	setIsSigning(isSigning);
	keyFromContext(context);
	
	/* optional padding attribute */
	uint32 padding;
	bool padPresent = context.getInt(CSSM_ATTRIBUTE_PADDING, padding);
	if(padPresent) {
		/* padding specified in context, convert to openssl style */
		switch(padding) {
			case CSSM_PADDING_NONE:
				mPadding = RSA_NO_PADDING;
				break;
			case CSSM_PADDING_PKCS1:
				mPadding = RSA_PKCS1_PADDING;
				break;
			default:
				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
		}
	}
	
	/* optional blinding attribute */
	uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING);
	if(blinding) {
		if(RSA_blinding_on(mRsaKey, NULL) <= 0) {
			/* actually no legit failures */
			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
		}
	}
	else {
		RSA_blinding_off(mRsaKey);
	}

	setInitFlag(true);
}
Beispiel #5
0
int check_validity_of_cert(
    const char *cFile, const unsigned char *md5_md, unsigned char *sfileMsg,
    const int sfsize, const char* caPath
) {
    int retval = 0;
    X509 *cert;
    X509_STORE *store;
    X509_LOOKUP *lookup;
    X509_STORE_CTX *ctx = 0;
    EVP_PKEY *pubKey;
    BIO *bio;

    bio = BIO_new(BIO_s_file());
    BIO_read_filename(bio, cFile);
    if (NULL == (cert = PEM_read_bio_X509(bio, NULL, 0, NULL))) {
	    BIO_vfree(bio);
	    return 0;
    }
    // verify certificate
    store = X509_STORE_new();
    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
    X509_LOOKUP_add_dir(lookup, (char *)caPath, X509_FILETYPE_PEM);
    if ((ctx = X509_STORE_CTX_new()) != 0) {
        if (X509_STORE_CTX_init(ctx, store, cert, 0) == 1)
            retval = X509_verify_cert(ctx);
        X509_STORE_CTX_free(ctx);
    }
    X509_STORE_free(store);
    
    if (retval != 1) {
        fprintf(stderr,"ERROR: Cannot verify certificate ('%s')\n", cFile);
        return 0;
    }        
    pubKey = X509_get_pubkey(cert);
    if (!pubKey) {
        X509_free(cert);
        BIO_vfree(bio);
        return 0;
    }
    if (pubKey->type == EVP_PKEY_RSA) {
        BN_CTX *c = BN_CTX_new();
        if (!c) {
	        X509_free(cert);
	        EVP_PKEY_free(pubKey);
	        BIO_vfree(bio);
	        return 0;
	    }
	    if (!RSA_blinding_on(pubKey->pkey.rsa, c)) {
	        X509_free(cert);
	        EVP_PKEY_free(pubKey);
	        BIO_vfree(bio);
	        BN_CTX_free(c);
	        return 0;
	    }
	    retval = RSA_verify(NID_md5, md5_md, MD5_DIGEST_LENGTH, sfileMsg, sfsize, pubKey->pkey.rsa);
	    RSA_blinding_off(pubKey->pkey.rsa);
	    BN_CTX_free(c);
    }
    if (pubKey->type == EVP_PKEY_DSA) {
        fprintf(stderr, "ERROR: DSA keys are not supported.\n");
        return 0;
    }
    EVP_PKEY_free(pubKey);
    X509_free(cert);
    BIO_vfree(bio);
    return retval;
}
/* called by CSPFullPluginSession */
void RSA_CryptContext::init(const Context &context, bool encoding /*= true*/)
{
	StLock<Mutex> _(gMutex());
	
	if(mInitFlag && !opStarted()) {
		/* reusing - e.g. query followed by encrypt */
		return;
	}

	/* optional mode to use alternate key class (e.g., decrypt with public key) */
	CSSM_KEYCLASS  keyClass;
    switch (context.getInt(CSSM_ATTRIBUTE_MODE)) {
        case CSSM_ALGMODE_PUBLIC_KEY:
			keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
            break;
        case CSSM_ALGMODE_PRIVATE_KEY:
			keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
            break;
        case CSSM_ALGMODE_NONE:	
			/* default, not present in context: infer from op type */
			keyClass = encoding ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY;
			break;
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
	}
	
	/* fetch key from context */
	if(mRsaKey == NULL) {
		assert(!opStarted());
		CSSM_DATA label = {0, NULL};
		mRsaKey = contextToRsaKey(context,
			session(),
			keyClass,
			encoding ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
			mAllocdRsaKey,
			label);
		if(label.Data) {
			mLabel.copy(label);
			mOaep = true;
			free(label.Data);
		}
	}
	else {
		assert(opStarted());	
	}

	unsigned cipherBlockSize = RSA_size(mRsaKey);
	unsigned plainBlockSize;

	/* padding - not present means value zero, CSSM_PADDING_NONE */
	uint32 padding = context.getInt(CSSM_ATTRIBUTE_PADDING);
	switch(padding) {
		case CSSM_PADDING_NONE:
			mPadding = RSA_NO_PADDING;
			plainBlockSize = cipherBlockSize;
			break;
		case CSSM_PADDING_PKCS1:
			mPadding = RSA_PKCS1_PADDING;
			plainBlockSize = cipherBlockSize - 11;
			break;
		case CSSM_PADDING_APPLE_SSLv2:
			rsaCryptDebug("RSA_CryptContext::init using CSSM_PADDING_APPLE_SSLv2");
			mPadding = RSA_SSLV23_PADDING;
			plainBlockSize = cipherBlockSize - 11;
			break;
		default:
			rsaCryptDebug("RSA_CryptContext::init bad padding (0x%x)",
				(unsigned)padding);
			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
	}
	
	/* optional blinding attribute */
	uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING);
	if(blinding) {
		if(RSA_blinding_on(mRsaKey, NULL) <= 0) {
			/* actually no legit failures */
			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
		}
	}
	else {
		RSA_blinding_off(mRsaKey);
	}

	/* finally, have BlockCryptor set up its stuff. */
	setup(encoding ? plainBlockSize  : cipherBlockSize, // blockSizeIn
		  encoding ? cipherBlockSize : plainBlockSize,	// blockSizeOut
		  false,										// pkcs5Pad
		  false,										// needsFinal
		  BCM_ECB,
		  NULL);											// IV
	mInitFlag = true;

}
Beispiel #7
0
// Signing functions
bool OSSLRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
		   ByteString& signature, const AsymMech::Type mechanism,
		   const void* param /* = NULL */, const size_t paramLen /* = 0 */)
{
	if (mechanism == AsymMech::RSA_PKCS)
	{
		// Separate implementation for RSA PKCS #1 signing without hash computation

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

			return false;
		}

		// In case of PKCS #1 signing the length of the input data may not exceed 40% of the
		// modulus size
		OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;

		size_t allowedLen = osslKey->getN().size() - 11;

		if (dataToSign.size() > allowedLen)
		{
			ERROR_MSG("Data to sign exceeds maximum for PKCS #1 signature");

			return false;
		}

		// Perform the signature operation
		signature.resize(osslKey->getN().size());

		RSA* rsa = osslKey->getOSSLKey();

		if (!RSA_blinding_on(rsa, NULL))
		{
			ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");

			return false;
		}

		int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_PKCS1_PADDING);

		RSA_blinding_off(rsa);

		if (sigLen == -1)
		{
			ERROR_MSG("An error occurred while performing a PKCS #1 signature");

			return false;
		}

		signature.resize(sigLen);

		return true;
	}
	else if (mechanism == AsymMech::RSA)
	{
		// Separate implementation for raw RSA signing

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

			return false;
		}

		// In case of raw RSA, the length of the input data must match the length of the modulus
		OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;

		if (dataToSign.size() != osslKey->getN().size())
		{
			ERROR_MSG("Size of data to sign does not match the modulus size");

			return false;
		}

		// Perform the signature operation
		signature.resize(osslKey->getN().size());

		RSA* rsa = osslKey->getOSSLKey();

		if (!RSA_blinding_on(rsa, NULL))
		{
			ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");

			return false;
		}

		int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_NO_PADDING);

		RSA_blinding_off(rsa);

		if (sigLen == -1)
		{
			ERROR_MSG("An error occurred while performing a raw RSA signature");

			return false;
		}

		signature.resize(sigLen);

		return true;
	}
	else
	{
		// Call default implementation
		return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
	}
}
Beispiel #8
0
bool OSSLRSA::signFinal(ByteString& signature)
{
	// Save necessary state before calling super class signFinal
	OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey;
	AsymMech::Type mechanism = currentMechanism;

	if (!AsymmetricAlgorithm::signFinal(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;

	// Resize the data block for the signature to the modulus size of the key
	signature.resize(pk->getN().size());

	// 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 signature operation
	unsigned int sigLen = signature.size();

	RSA* rsa = pk->getOSSLKey();

	if (!RSA_blinding_on(rsa, NULL))
	{
		ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key");

		return false;
	}

	bool rv;

	if (isPSS)
	{
		ByteString em;
		em.resize(pk->getN().size());

		rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0],
						hash, sLen) == 1);
		if (!rv)
		{
			ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error());
		}
		else
		{
			int result = RSA_private_encrypt(em.size(), &em[0], &signature[0],
							 pk->getOSSLKey(), RSA_NO_PADDING);
			if (result >= 0)
			{
				sigLen = result;
				rv = true;
			}
			else
			{
				rv = false;
				ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error());
			}
		}
	}
	else
	{
		rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0],
			       &sigLen, pk->getOSSLKey()) == 1);
	}

	RSA_blinding_off(rsa);

	signature.resize(sigLen);

	return rv;
}
Beispiel #9
0
		inline void rsa_key::disable_blinding() const
		{
			RSA_blinding_off(ptr().get());
		}