+typedef struct {
+ SilcStack stack;
+ unsigned char *pubdata;
+ SilcUInt32 pubdata_len;
+ SilcAuthGenerated generated;
+ void *context;
+} *SilcAuthGenerateContext;
+
+/* Signature callback */
+
+static void
+silc_auth_public_key_auth_generate_cb(SilcBool success,
+ const unsigned char *signature,
+ SilcUInt32 signature_len,
+ void *context)
+{
+ SilcAuthGenerateContext a = context;
+ SilcStack stack = a->stack;
+ SilcBuffer buf;
+
+ if (!success) {
+ a->generated(NULL, context);
+ silc_sfree(stack, a->pubdata);
+ silc_sfree(stack, a);
+ silc_stack_free(stack);
+ return;
+ }
+
+ /* Encode Authentication Payload */
+ buf = silc_auth_payload_encode(stack, SILC_AUTH_PUBLIC_KEY, a->pubdata,
+ a->pubdata_len, signature, signature_len);
+
+ a->generated(buf, context);
+
+ silc_buffer_sfree(stack, buf);
+ silc_sfree(stack, a->pubdata);
+ silc_sfree(stack, a);
+ silc_stack_free(stack);
+}
+
+/* Generates Authentication Payload with authentication data. This is used
+ to do public key based authentication. This generates the random data
+ and the actual authentication data. Returns NULL on error. */
+
+SilcAsyncOperation
+silc_auth_public_key_auth_generate(SilcPublicKey public_key,
+ SilcPrivateKey private_key,
+ SilcRng rng, SilcHash hash,
+ const void *id, SilcIdType type,
+ SilcAuthGenerated generated,
+ void *context)
+{
+ unsigned char randomdata[256];
+
+ /* Get random data */
+ if (rng)
+ silc_rng_get_rn_data(rng, sizeof(randomdata), randomdata,
+ sizeof(randomdata));
+ else
+ silc_rng_global_get_rn_data(rng, sizeof(randomdata), randomdata,
+ sizeof(randomdata));
+
+ return silc_auth_public_key_auth_generate_wpub(public_key, private_key,
+ randomdata, sizeof(randomdata),
+ hash, rng, id, type, generated,
+ context);
+}
+