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