Beispiel #1
0
PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url,
					PKCS11_HANDLER *lib, void *driver) {

	PKI_RSA_KEY *ret = NULL;

	CK_OBJECT_HANDLE *handler_pubkey = NULL;
	CK_OBJECT_HANDLE *handler_privkey = NULL;

	CK_ATTRIBUTE privTemp[32];
	CK_ATTRIBUTE pubTemp[32];

	CK_RV rv;

	CK_MECHANISM * RSA_MECH_PTR = NULL;

	CK_ULONG i = 0;
	CK_ULONG n = 0;

	CK_ULONG bits = 0;

	size_t label_len = 0;

	unsigned char *data = NULL;
	CK_BYTE *esp = NULL;
	CK_ULONG size = 0;

	BIGNUM *bn = NULL;
	BIGNUM *id_num = NULL;

	char *id     = NULL;
	int   id_len = 8; 

	int idx = 0;

	if ( !url || !url->addr ) {
		PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
		return ( NULL );
	}

	label_len = strlen( url->addr );

	/* Check the min size for the key */
	if ( kp ) {
		if( kp->bits < PKI_RSA_KEY_MIN_SIZE ) {
			PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL);
		} else {
			bits = (CK_ULONG) kp->bits;
		}
	} else {
		bits = PKI_RSA_KEY_DEFAULT_SIZE;
	}

	// Look for a supported key generation mechanism
	for (idx = 0; idx < RSA_MECH_LIST_SIZE; idx++) {

		// Checks if the mechanism is supported
		if (HSM_PKCS11_check_mechanism(lib, 
				RSA_MECH_LIST[idx].mechanism) == PKI_OK) {

			// Set the pointer to the supported mechanism
			RSA_MECH_PTR = &RSA_MECH_LIST[idx];

			// Debugging Information
			PKI_DEBUG("Found RSA KEY GEN MECHANISM 0x%8.8X",
				RSA_MECH_LIST[idx].mechanism);

			// Breaks out of the loop
			break;

		} else {

			// Let's provide debug information for not-supported mechs
			PKI_DEBUG("RSA KEY GEN MECHANISM 0x%8.8X not supported",
				RSA_MECH_LIST[idx].mechanism);
		}
	}

	// If no key gen algors are supported, abort
	if (RSA_MECH_PTR == NULL) {
		PKI_ERROR(PKI_ERR_HSM_KEYPAIR_GENERATE, "No KeyGen Mechanisms supported!");
		return NULL;
	}

PKI_DEBUG("BITS FOR KEY GENERATION %lu (def: %lu)", bits, PKI_RSA_KEY_DEFAULT_SIZE);

	if (kp && kp->rsa.exponent > 3) {
		// TO be Implemented
	} else {
		if( BN_hex2bn(&bn, "10001") == 0 ) {
			PKI_log_debug("ERROR, can not convert 10001 to BIGNUM");
			return ( NULL );
		}
	}

	if( url->path != NULL ) {
		if((BN_hex2bn(&id_num, url->path )) == 0 ) {
			PKI_log_debug("ERROR, can not convert %s to BIGNUM",
						url->path );
			return ( NULL );
		}
		if((id_len = BN_num_bytes(id_num)) < 0 ) {
			if ( bn ) BN_free ( bn );
			if ( id_num ) BN_free ( id_num );
			return ( NULL );
		}
		id = PKI_Malloc ( (size_t ) id_len );
		BN_bn2bin( id_num, (unsigned char *) id );
	} else {
		id_len = 10;
		if((id = PKI_Malloc ( (size_t) id_len )) == NULL ) {
			if ( bn ) BN_free ( bn );
			return ( NULL );
		}

		if( RAND_bytes( (unsigned char *) id, id_len) == 0 ) {
			PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate RAND bytes");
			if( bn ) BN_free ( bn );
        	        return ( NULL );
        	}
	}

	PKI_DEBUG("Setting the Bits to %lu", bits);

	/* Setting Attributes for the public Key Template */
	n = 0;
	//HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &pubTemp[n++]);
	//HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &pubTemp[n++]);
	HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &pubTemp[n++]);

	HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &pubTemp[n++]);
	HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &pubTemp[n++]);
	HSM_PKCS11_set_attr_bool( CKA_VERIFY, CK_TRUE, &pubTemp[n++]);
	HSM_PKCS11_set_attr_bool( CKA_WRAP, CK_TRUE, &pubTemp[n++]);

	HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &pubTemp[n++]);
	HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &pubTemp[n++]);
	HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &pubTemp[n++]);

	/* Setting Attributes for the private Key Template */
	i = 0;
	//HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &privTemp[i++]);
	//HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &privTemp[i++]);
	//HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &privTemp[i++]);

	HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_PRIVATE, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_SENSITIVE, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_DECRYPT, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_SIGN, CK_TRUE, &privTemp[i++]);
	// HSM_PKCS11_set_attr_bool( CKA_NEVER_EXTRACTABLE, CK_TRUE, 
	// 						&privTemp[i++]);
	// HSM_PKCS11_set_attr_bool( CKA_EXTRACTABLE, CK_FALSE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_UNWRAP, CK_TRUE, &privTemp[i++]);

	// HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &privTemp[i++]);
	HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &privTemp[i++]);
	HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &privTemp[i++]);

	/* Allocate the handlers for pub and priv keys */
	handler_pubkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( 
						sizeof( CK_OBJECT_HANDLE ));
	handler_privkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( 
						sizeof( CK_OBJECT_HANDLE ));

	if( !handler_pubkey || !handler_privkey ) {
		if ( bn ) BN_free ( bn );
		if ( esp ) PKI_Free ( esp );
		return ( NULL );
	}

	PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Generating a new Key ... ");
	rv = lib->callbacks->C_GenerateKeyPair (
			lib->session, RSA_MECH_PTR, 
			pubTemp, n,
			privTemp, i,
			handler_pubkey, 
			handler_privkey);

	if( rv != CKR_OK ) {
		if ( rv == CKR_MECHANISM_INVALID ) {
			PKI_log_err("HSM_PKCS11_KEYPAIR_new()::RSA Algorithm "
				"is not supported by the Token" );
		} else {
			PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed with "
					"code 0x%8.8X", rv );
		};
		if ( bn ) BN_free ( bn );
		if ( esp ) PKI_Free ( esp );
		return ( NULL );
	}

	/* Clean up the Memory we are not using anymore */
	if ( bn ) BN_free ( bn );
	if ( esp ) PKI_Free ( esp );

	/* Generate a new RSA container */
	if((ret = RSA_new()) == NULL ) {
		goto err;
	};
	
	if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session,
			CKA_PUBLIC_EXPONENT, (void **) &data, 
						&size, lib ) != PKI_OK ) {
		goto err;
	};

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	RSA_set0_key(ret, NULL, BN_bin2bn( data, (int) size, NULL), NULL);
#else
	ret->e = BN_bin2bn( data, (int) size, NULL );
#endif
	PKI_Free ( data );
	data = NULL;

	if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session,
			CKA_MODULUS, (void **) &data, &size, lib ) != PKI_OK ) {
		goto err;
	};

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	RSA_set0_key(ret, BN_bin2bn(data, (int) size, NULL), NULL, NULL);
#else
	ret->n = BN_bin2bn( data, (int) size, NULL );
#endif
	PKI_Free ( data );
	data = NULL;

	/* Let's get the Attributes from the Keypair and store into the
	   key's pointer */
	RSA_set_method( ret, HSM_PKCS11_get_rsa_method());

#ifdef RSA_FLAG_SIGN_VER
# if OPENSSL_VERSION_NUMBER >= 0x1010000fL 
	RSA_set_flags( ret, RSA_FLAG_SIGN_VER);
# else
	ret->flags |= RSA_FLAG_SIGN_VER;
# endif
#endif

	/* Push the priv and pub key handlers to the rsa->ex_data */
	RSA_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver );
	RSA_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey );
	RSA_set_ex_data( ret, KEYPAIR_PUBKEY_HANDLER_IDX, handler_pubkey );

	/* Cleanup the memory for Templates */
	HSM_PKCS11_clean_template ( pubTemp, (int) n );
	HSM_PKCS11_clean_template ( privTemp, (int) i );

	/* Let's return the RSA_KEY infrastructure */
	return (ret);

err:
	if( ret ) RSA_free ((RSA *) ret );

	if ( handler_pubkey ) {
		if((rv = lib->callbacks->C_DestroyObject( lib->session, 
					*handler_pubkey )) != CKR_OK ) {
		PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed to delete "
			"pubkey object");
		};
		PKI_Free ( handler_pubkey );
	}

	if( handler_privkey ) {
		if((rv = lib->callbacks->C_DestroyObject( lib->session, 
					*handler_privkey)) != CKR_OK ) {
		PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed to delete "
			"privkey object");
		};
		PKI_Free ( handler_privkey );
	}

	PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Key material DELETED!");

	return ( NULL );

}
Beispiel #2
0
int main(int argc, char *argv[])
{
    int err = 0;
    int v;
    RSA *key;
    unsigned char ptext[256];
    unsigned char ctext[256];
    static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
    unsigned char ctext_ex[256];
    int plen;
    int clen = 0;
    int num;
    int n;

    CRYPTO_set_mem_debug(1);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */

    plen = sizeof(ptext_ex) - 1;

    for (v = 0; v < 6; v++) {
        key = RSA_new();
        switch (v % 3) {
        case 0:
            clen = key1(key, ctext_ex);
            break;
        case 1:
            clen = key2(key, ctext_ex);
            break;
        case 2:
            clen = key3(key, ctext_ex);
            break;
        }
        if (v / 3 >= 1)
            RSA_set_flags(key, RSA_FLAG_NO_CONSTTIME);

        num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
                                 RSA_PKCS1_PADDING);
        if (num != clen) {
            printf("PKCS#1 v1.5 encryption failed!\n");
            err = 1;
            goto oaep;
        }

        num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING);
        if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
            printf("PKCS#1 v1.5 decryption failed!\n");
            err = 1;
        } else
            printf("PKCS #1 v1.5 encryption/decryption ok\n");

 oaep:
        ERR_clear_error();
        num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
                                 RSA_PKCS1_OAEP_PADDING);
        if (num == -1 && pad_unknown()) {
            printf("No OAEP support\n");
            goto next;
        }
        if (num != clen) {
            printf("OAEP encryption failed!\n");
            err = 1;
            goto next;
        }

        num = RSA_private_decrypt(num, ctext, ptext, key,
                                  RSA_PKCS1_OAEP_PADDING);
        if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
            printf("OAEP decryption (encrypted data) failed!\n");
            err = 1;
        } else if (memcmp(ctext, ctext_ex, num) == 0)
            printf("OAEP test vector %d passed!\n", v);

        /*
         * Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT). Try
         * decrypting ctext_ex
         */

        num = RSA_private_decrypt(clen, ctext_ex, ptext, key,
                                  RSA_PKCS1_OAEP_PADDING);

        if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
            printf("OAEP decryption (test vector data) failed!\n");
            err = 1;
        } else
            printf("OAEP encryption/decryption ok\n");

        /* Try decrypting corrupted ciphertexts. */
        for (n = 0; n < clen; ++n) {
            ctext[n] ^= 1;
            num = RSA_private_decrypt(clen, ctext, ptext, key,
                                          RSA_PKCS1_OAEP_PADDING);
            if (num > 0) {
                printf("Corrupt data decrypted!\n");
                err = 1;
                break;
            }
            ctext[n] ^= 1;
        }

        /* Test truncated ciphertexts, as well as negative length. */
        for (n = -1; n < clen; ++n) {
            num = RSA_private_decrypt(n, ctext, ptext, key,
                                      RSA_PKCS1_OAEP_PADDING);
            if (num > 0) {
                printf("Truncated data decrypted!\n");
                err = 1;
                break;
            }
        }

 next:
        RSA_free(key);
    }

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    if (CRYPTO_mem_leaks_fp(stderr) <= 0)
        err = 1;
#endif

    return err;
}