components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.c
changeset 1597 392a401c6d27
parent 1552 a35bff6c7563
child 1665 9e945128be3b
equal deleted inserted replaced
1596:59869c4257d0 1597:392a401c6d27
   315 static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
   315 static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
   316 static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
   316 static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
   317 static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
   317 static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
   318 
   318 
   319 static int pk11_choose_slots(int *any_slot_found);
   319 static int pk11_choose_slots(int *any_slot_found);
       
   320 static void pk11_choose_rand_slot(CK_TOKEN_INFO token_info,
       
   321     CK_SLOT_ID current_slot);
       
   322 static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info,
       
   323     CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv,
       
   324     int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar);
       
   325 static void pk11_choose_cipher_digest(int *local_cipher_nids,
       
   326     int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist,
       
   327     CK_SLOT_ID current_slot);
   320 static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
   328 static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
   321     CK_SLOT_ID current_slot, int *current_slot_n_cipher,
   329     CK_SLOT_ID current_slot, int *current_slot_n_cipher,
   322     int *local_cipher_nids);
   330     int *local_cipher_nids);
   323 static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
   331 static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
   324     CK_SLOT_ID current_slot, int *current_slot_n_digest,
   332     CK_SLOT_ID current_slot, int *current_slot_n_digest,
  3026 	CK_MECHANISM_INFO mech_info;
  3034 	CK_MECHANISM_INFO mech_info;
  3027 	CK_TOKEN_INFO token_info;
  3035 	CK_TOKEN_INFO token_info;
  3028 	int i;
  3036 	int i;
  3029 	CK_RV rv;
  3037 	CK_RV rv;
  3030 	CK_SLOT_ID best_pubkey_slot_sofar;
  3038 	CK_SLOT_ID best_pubkey_slot_sofar;
  3031 #ifdef DEBUG_SLOT_SELECTION
       
  3032 	CK_SLOT_ID best_cd_slot_sofar;
       
  3033 #endif
       
  3034 	int slot_n_cipher = -1;
       
  3035 	int slot_n_digest = -1;
       
  3036 	CK_SLOT_ID current_slot = 0;
  3039 	CK_SLOT_ID current_slot = 0;
  3037 	int current_slot_n_cipher = 0;
       
  3038 	int current_slot_n_digest = 0;
       
  3039 	int best_number_of_mechs = 0;
  3040 	int best_number_of_mechs = 0;
  3040 	int current_number_of_mechs = 0;
       
  3041 	int local_cipher_nids[PK11_CIPHER_MAX];
  3041 	int local_cipher_nids[PK11_CIPHER_MAX];
  3042 	int local_digest_nids[PK11_DIGEST_MAX];
  3042 	int local_digest_nids[PK11_DIGEST_MAX];
  3043 
  3043 
  3044 	/* let's initialize the output parameter */
  3044 	/* let's initialize the output parameter */
  3045 	if (any_slot_found != NULL)
  3045 	if (any_slot_found != NULL)
  3082 	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
  3082 	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
  3083 
  3083 
  3084 	pubkey_SLOTID = pSlotList[0];
  3084 	pubkey_SLOTID = pSlotList[0];
  3085 	for (i = 0; i < ulSlotCount; i++)
  3085 	for (i = 0; i < ulSlotCount; i++)
  3086 		{
  3086 		{
  3087 		CK_BBOOL slot_has_rsa = CK_FALSE;
       
  3088 		CK_BBOOL slot_has_dsa = CK_FALSE;
       
  3089 		CK_BBOOL slot_has_dh = CK_FALSE;
       
  3090 		current_slot = pSlotList[i];
  3087 		current_slot = pSlotList[i];
  3091 		DEBUG_SLOT_SEL("%s: == checking slot: %d ==\n", PK11_DBG,
  3088 		DEBUG_SLOT_SEL("%s: == checking slot: %d ==\n", PK11_DBG,
  3092 		    current_slot);
  3089 		    current_slot);
  3093 		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
  3090 		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
  3094 		if (rv != CKR_OK)
  3091 		if (rv != CKR_OK)
  3095 			continue;
  3092 			continue;
  3096 
  3093 
  3097 		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
  3094 		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
  3098 		    token_info.label);
  3095 		    token_info.label);
  3099 
  3096 
  3100 		DEBUG_SLOT_SEL("%s: checking rand slots\n", PK11_DBG);
  3097 		pk11_choose_rand_slot(token_info, current_slot);
  3101 
  3098 
  3102 		if (((token_info.flags & CKF_RNG) != 0) && !pk11_have_random)
  3099 		pk11_choose_pubkey_slot(mech_info, token_info, current_slot,
  3103 			{
  3100 			rv, best_number_of_mechs, best_pubkey_slot_sofar);
  3104 			DEBUG_SLOT_SEL(
  3101 
  3105 			    "%s: this token has CKF_RNG flag\n", PK11_DBG);
  3102 		pk11_choose_cipher_digest(&local_cipher_nids,
  3106 			pk11_have_random = CK_TRUE;
  3103 			&local_digest_nids, pFuncList, current_slot);
  3107 			rand_SLOTID = current_slot;
       
  3108 			}
       
  3109 
       
  3110 		DEBUG_SLOT_SEL("%s: checking pubkey slots\n", PK11_DBG);
       
  3111 
       
  3112 		current_number_of_mechs = 0;
       
  3113 #ifndef OPENSSL_NO_RSA
       
  3114 		/*
       
  3115 		 * Check if this slot is capable of signing and
       
  3116 		 * verifying with CKM_RSA_PKCS.
       
  3117 		 */
       
  3118 		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
       
  3119 			&mech_info);
       
  3120 
       
  3121 		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3122 				(mech_info.flags & CKF_VERIFY)))
       
  3123 			{
       
  3124 			/*
       
  3125 			 * Check if this slot is capable of encryption,
       
  3126 			 * decryption, sign, and verify with CKM_RSA_X_509.
       
  3127 			 */
       
  3128 			rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3129 			    CKM_RSA_X_509, &mech_info);
       
  3130 
       
  3131 			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3132 			    (mech_info.flags & CKF_VERIFY) &&
       
  3133 			    (mech_info.flags & CKF_ENCRYPT) &&
       
  3134 			    (mech_info.flags & CKF_VERIFY_RECOVER) &&
       
  3135 			    (mech_info.flags & CKF_DECRYPT)))
       
  3136 				{
       
  3137 				slot_has_rsa = CK_TRUE;
       
  3138 				current_number_of_mechs++;
       
  3139 				}
       
  3140 			}
       
  3141 #endif	/* OPENSSL_NO_RSA */
       
  3142 
       
  3143 #ifndef OPENSSL_NO_DSA
       
  3144 		/*
       
  3145 		 * Check if this slot is capable of signing and
       
  3146 		 * verifying with CKM_DSA.
       
  3147 		 */
       
  3148 		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
       
  3149 			&mech_info);
       
  3150 		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3151 		    (mech_info.flags & CKF_VERIFY)))
       
  3152 			{
       
  3153 			slot_has_dsa = CK_TRUE;
       
  3154 			current_number_of_mechs++;
       
  3155 			}
       
  3156 
       
  3157 #endif	/* OPENSSL_NO_DSA */
       
  3158 
       
  3159 #ifndef OPENSSL_NO_DH
       
  3160 		/*
       
  3161 		 * Check if this slot is capable of DH key generataion and
       
  3162 		 * derivation.
       
  3163 		 */
       
  3164 		rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3165 		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
       
  3166 
       
  3167 		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
       
  3168 			{
       
  3169 			rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3170 				CKM_DH_PKCS_DERIVE, &mech_info);
       
  3171 			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
       
  3172 				{
       
  3173 				slot_has_dh = CK_TRUE;
       
  3174 				current_number_of_mechs++;
       
  3175 				}
       
  3176 			}
       
  3177 #endif	/* OPENSSL_NO_DH */
       
  3178 
       
  3179 		if (current_number_of_mechs > best_number_of_mechs)
       
  3180 			{
       
  3181 			best_pubkey_slot_sofar = current_slot;
       
  3182 			pk11_have_rsa = slot_has_rsa;
       
  3183 			pk11_have_dsa = slot_has_dsa;
       
  3184 			pk11_have_dh = slot_has_dh;
       
  3185 			best_number_of_mechs = current_number_of_mechs;
       
  3186 			/*
       
  3187 			 * Cache the flags for later use. We might need those if
       
  3188 			 * RSA keys by reference feature is used.
       
  3189 			 */
       
  3190 			pubkey_token_flags = token_info.flags;
       
  3191 			DEBUG_SLOT_SEL("%s: pubkey flags changed to "
       
  3192 			    "%lu.\n", PK11_DBG, pubkey_token_flags);
       
  3193 			}
       
  3194 
       
  3195 		DEBUG_SLOT_SEL("%s: checking cipher/digest\n", PK11_DBG);
       
  3196 
       
  3197 		current_slot_n_cipher = 0;
       
  3198 		current_slot_n_digest = 0;
       
  3199 		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
       
  3200 		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
       
  3201 
       
  3202 		pk11_find_symmetric_ciphers(pFuncList, current_slot,
       
  3203 		    &current_slot_n_cipher, local_cipher_nids);
       
  3204 
       
  3205 		pk11_find_digests(pFuncList, current_slot,
       
  3206 		    &current_slot_n_digest, local_digest_nids);
       
  3207 
       
  3208 		DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
       
  3209 			current_slot_n_cipher);
       
  3210 		DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
       
  3211 			current_slot_n_digest);
       
  3212 
       
  3213 		/*
       
  3214 		 * If the current slot supports more ciphers/digests than
       
  3215 		 * the previous best one we change the current best to this one,
       
  3216 		 * otherwise leave it where it is.
       
  3217 		 */
       
  3218 		if ((current_slot_n_cipher + current_slot_n_digest) >
       
  3219 		    (slot_n_cipher + slot_n_digest))
       
  3220 			{
       
  3221 			DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
       
  3222 				PK11_DBG, current_slot);
       
  3223 			SLOTID = current_slot;
       
  3224 #ifdef DEBUG_SLOT_SELECTION
       
  3225 			best_cd_slot_sofar = current_slot;
       
  3226 #endif
       
  3227 			cipher_count = slot_n_cipher = current_slot_n_cipher;
       
  3228 			digest_count = slot_n_digest = current_slot_n_digest;
       
  3229 			(void) memcpy(cipher_nids, local_cipher_nids,
       
  3230 			    sizeof (local_cipher_nids));
       
  3231 			(void) memcpy(digest_nids, local_digest_nids,
       
  3232 			    sizeof (local_digest_nids));
       
  3233 			}
       
  3234 
       
  3235 		DEBUG_SLOT_SEL("%s: best cipher/digest slot so far: %d\n",
       
  3236 			PK11_DBG, best_cd_slot_sofar);
       
  3237 		}
  3104 		}
  3238 
  3105 
  3239 	if (best_number_of_mechs == 0)
  3106 	if (best_number_of_mechs == 0)
  3240 		{
  3107 		{
  3241 		DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
  3108 		DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
  3264 #endif	/* SOLARIS_HW_SLOT_SELECTION */
  3131 #endif	/* SOLARIS_HW_SLOT_SELECTION */
  3265 
  3132 
  3266 	if (any_slot_found != NULL)
  3133 	if (any_slot_found != NULL)
  3267 		*any_slot_found = 1;
  3134 		*any_slot_found = 1;
  3268 	return (1);
  3135 	return (1);
       
  3136 	}
       
  3137 
       
  3138 static void pk11_choose_rand_slot(CK_TOKEN_INFO token_info,
       
  3139     CK_SLOT_ID current_slot)
       
  3140 	{
       
  3141 	DEBUG_SLOT_SEL("%s: checking rand slots\n", PK11_DBG);
       
  3142 	if (((token_info.flags & CKF_RNG) != 0) && !pk11_have_random)
       
  3143 		{
       
  3144 		DEBUG_SLOT_SEL("%s: this token has CKF_RNG flag\n", PK11_DBG);
       
  3145 		pk11_have_random = CK_TRUE;
       
  3146 		rand_SLOTID = current_slot;
       
  3147 		}
       
  3148 	}
       
  3149 
       
  3150 static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info,
       
  3151     CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv,
       
  3152     int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar)
       
  3153 	{
       
  3154 	CK_BBOOL slot_has_rsa = CK_FALSE;
       
  3155 	CK_BBOOL slot_has_dsa = CK_FALSE;
       
  3156 	CK_BBOOL slot_has_dh = CK_FALSE;
       
  3157 	int current_number_of_mechs = 0;
       
  3158 
       
  3159 	DEBUG_SLOT_SEL("%s: checking pubkey slots\n", PK11_DBG);
       
  3160 
       
  3161 #ifndef OPENSSL_NO_RSA
       
  3162 	/*
       
  3163 	 * Check if this slot is capable of signing and
       
  3164 	 * verifying with CKM_RSA_PKCS.
       
  3165 	 */
       
  3166 	rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
       
  3167 		&mech_info);
       
  3168 
       
  3169 	if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3170 			(mech_info.flags & CKF_VERIFY)))
       
  3171 		{
       
  3172 		/*
       
  3173 		 * Check if this slot is capable of encryption,
       
  3174 		 * decryption, sign, and verify with CKM_RSA_X_509.
       
  3175 		 */
       
  3176 		rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3177 		    CKM_RSA_X_509, &mech_info);
       
  3178 
       
  3179 		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3180 		    (mech_info.flags & CKF_VERIFY) &&
       
  3181 		    (mech_info.flags & CKF_ENCRYPT) &&
       
  3182 		    (mech_info.flags & CKF_VERIFY_RECOVER) &&
       
  3183 		    (mech_info.flags & CKF_DECRYPT)))
       
  3184 			{
       
  3185 			slot_has_rsa = CK_TRUE;
       
  3186 			current_number_of_mechs++;
       
  3187 			}
       
  3188 		}
       
  3189 #endif  /* OPENSSL_NO_RSA */
       
  3190 
       
  3191 #ifndef OPENSSL_NO_DSA
       
  3192 	/*
       
  3193 	 * Check if this slot is capable of signing and
       
  3194 	 * verifying with CKM_DSA.
       
  3195 	 */
       
  3196 	rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
       
  3197 		&mech_info);
       
  3198 	if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3199 	    (mech_info.flags & CKF_VERIFY)))
       
  3200 		{
       
  3201 		slot_has_dsa = CK_TRUE;
       
  3202 		current_number_of_mechs++;
       
  3203 		}
       
  3204 #endif  /* OPENSSL_NO_DSA */
       
  3205 
       
  3206 #ifndef OPENSSL_NO_DH
       
  3207 	/*
       
  3208 	 * Check if this slot is capable of DH key generataion and
       
  3209 	 * derivation.
       
  3210 	 */
       
  3211 	rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3212 	    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
       
  3213 
       
  3214 	if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
       
  3215 		{
       
  3216 		rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3217 			CKM_DH_PKCS_DERIVE, &mech_info);
       
  3218 		if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
       
  3219 			{
       
  3220 			slot_has_dh = CK_TRUE;
       
  3221 			current_number_of_mechs++;
       
  3222 			}
       
  3223 		}
       
  3224 #endif  /* OPENSSL_NO_DH */
       
  3225 
       
  3226 	if (current_number_of_mechs > best_number_of_mechs)
       
  3227 		{
       
  3228 		best_pubkey_slot_sofar = current_slot;
       
  3229 		pk11_have_rsa = slot_has_rsa;
       
  3230 		pk11_have_dsa = slot_has_dsa;
       
  3231 		pk11_have_dh = slot_has_dh;
       
  3232 		best_number_of_mechs = current_number_of_mechs;
       
  3233 		/*
       
  3234 		 * Cache the flags for later use. We might need those if
       
  3235 		 * RSA keys by reference feature is used.
       
  3236 		 */
       
  3237 		pubkey_token_flags = token_info.flags;
       
  3238 		DEBUG_SLOT_SEL("%s: pubkey flags changed to "
       
  3239 		    "%lu.\n", PK11_DBG, pubkey_token_flags);
       
  3240 		}
       
  3241 	}
       
  3242 
       
  3243 static void pk11_choose_cipher_digest(int *local_cipher_nids,
       
  3244     int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist,
       
  3245     CK_SLOT_ID current_slot)
       
  3246 	{
       
  3247 	int current_slot_n_cipher = 0;
       
  3248 	int current_slot_n_digest = 0;
       
  3249 
       
  3250 	DEBUG_SLOT_SEL("%s: checking cipher/digest\n", PK11_DBG);
       
  3251 
       
  3252 	(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
       
  3253 	(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
       
  3254 
       
  3255 	pk11_find_symmetric_ciphers(pFuncList, current_slot,
       
  3256 	    &current_slot_n_cipher, local_cipher_nids);
       
  3257 
       
  3258 	pk11_find_digests(pFuncList, current_slot,
       
  3259 	    &current_slot_n_digest, local_digest_nids);
       
  3260 
       
  3261 	DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
       
  3262 		current_slot_n_cipher);
       
  3263 	DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
       
  3264 		current_slot_n_digest);
       
  3265 	/*
       
  3266 	 * If the current slot supports more ciphers/digests than
       
  3267 	 * the previous best one we change the current best to this one,
       
  3268 	 * otherwise leave it where it is.
       
  3269 	 */
       
  3270 	if ((current_slot_n_cipher + current_slot_n_digest) >
       
  3271 	    (cipher_count + digest_count))
       
  3272 		{
       
  3273 		DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
       
  3274 			PK11_DBG, current_slot);
       
  3275 		SLOTID = current_slot;
       
  3276 		cipher_count = current_slot_n_cipher;
       
  3277 		digest_count = current_slot_n_digest;
       
  3278 		(void) memcpy(cipher_nids, local_cipher_nids,
       
  3279 			sizeof (local_cipher_nids));
       
  3280 		(void) memcpy(digest_nids, local_digest_nids,
       
  3281 			sizeof (local_digest_nids));
       
  3282 		}
  3269 	}
  3283 	}
  3270 
  3284 
  3271 static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
  3285 static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
  3272     int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
  3286     int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
  3273     PK11_CIPHER *cipher)
  3287     PK11_CIPHER *cipher)