+ ske->ke1_payload = recv_payload;
+
+ /* Verify the received public key and verify the signature if we are
+ doing mutual authentication. */
+ if (ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
+ SilcPublicKey public_key = NULL;
+ unsigned char hash[32];
+ unsigned int hash_len;
+
+ SILC_LOG_DEBUG(("We are doing mutual authentication"));
+ SILC_LOG_DEBUG(("Verifying public key"));
+
+ if (!silc_pkcs_public_key_decode(recv_payload->pk_data,
+ recv_payload->pk_len,
+ &public_key)) {
+ status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
+ return status;
+ }
+
+ if (verify_key) {
+ status = (*verify_key)(ske, recv_payload->pk_data, recv_payload->pk_len,
+ recv_payload->pk_type, verify_context);
+ if (status != SILC_SKE_STATUS_OK)
+ return status;
+ }
+
+ SILC_LOG_DEBUG(("Public key is authentic"));
+
+ /* Compute the hash value */
+ status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
+ if (status != SILC_SKE_STATUS_OK)
+ return status;
+
+ SILC_LOG_DEBUG(("Verifying signature"));
+
+ /* Verify signature */
+ silc_pkcs_public_key_data_set(ske->prop->pkcs, public_key->pk,
+ public_key->pk_len);
+ if (silc_pkcs_verify(ske->prop->pkcs, recv_payload->sign_data,
+ recv_payload->sign_len, hash, hash_len) == FALSE) {
+
+ SILC_LOG_DEBUG(("Signature don't match"));
+
+ status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
+ return status;
+ }
+
+ SILC_LOG_DEBUG(("Signature is Ok"));
+
+ silc_pkcs_public_key_free(public_key);
+ memset(hash, 'F', hash_len);
+ }
+