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, |
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 ¤t_slot_n_cipher, local_cipher_nids); |
|
3204 |
|
3205 pk11_find_digests(pFuncList, current_slot, |
|
3206 ¤t_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 ¤t_slot_n_cipher, local_cipher_nids); |
|
3257 |
|
3258 pk11_find_digests(pFuncList, current_slot, |
|
3259 ¤t_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) |