+
+/* Verifies the authentication data directly from the Authentication
+ Payload. Supports all authentication methods. If the authentication
+ method is passphrase based then the `auth_data' and `auth_data_len'
+ are the passphrase and its length. If the method is public key
+ authentication then the `auth_data' is the SilcPublicKey and the
+ `auth_data_len' is ignored. */
+
+int silc_auth_verify(SilcAuthPayload payload, SilcAuthMethod auth_method,
+ void *auth_data, uint32 auth_data_len,
+ SilcHash hash, void *id, SilcIdType type)
+{
+ SILC_LOG_DEBUG(("Verifying authentication"));
+
+ if (auth_method != payload->auth_method)
+ return FALSE;
+
+ switch (payload->auth_method) {
+ case SILC_AUTH_NONE:
+ /* No authentication */
+ SILC_LOG_DEBUG(("No authentication required"));
+ return TRUE;
+
+ case SILC_AUTH_PASSWORD:
+ /* Passphrase based authentication. The `pkcs', `hash', `id' and `type'
+ arguments are not needed. */
+ if (!memcmp(payload->auth_data, auth_data, payload->auth_len)) {
+ SILC_LOG_DEBUG(("Authentication successful"));
+ return TRUE;
+ }
+ break;
+
+ case SILC_AUTH_PUBLIC_KEY:
+ /* Public key based authentication */
+ return silc_auth_public_key_auth_verify(payload, (SilcPublicKey)auth_data,
+ hash, id, type);
+ break;
+
+ default:
+ break;
+ }
+
+ SILC_LOG_DEBUG(("Authentication failed"));
+
+ return FALSE;
+}
+
+/* Same as above but parses the authentication payload before verify. */
+
+int silc_auth_verify_data(unsigned char *payload, uint32 payload_len,
+ SilcAuthMethod auth_method, void *auth_data,
+ uint32 auth_data_len, SilcHash hash,
+ void *id, SilcIdType type)
+{
+ SilcAuthPayload auth_payload;
+ int ret;
+
+ auth_payload = silc_auth_payload_parse(payload, payload_len);
+ if (!auth_payload)
+ return FALSE;
+
+ ret = silc_auth_verify(auth_payload, auth_method, auth_data, auth_data_len,
+ hash, id, type);
+
+ silc_auth_payload_free(auth_payload);
+
+ return ret;
+}
+
+/******************************************************************************
+
+ Key Agreement Payload
+
+******************************************************************************/
+
+/* The Key Agreement protocol structure */
+struct SilcKeyAgreementPayloadStruct {
+ uint16 hostname_len;
+ unsigned char *hostname;
+ uint32 port;
+};
+
+/* Parses and returns an allocated Key Agreement payload. */
+
+SilcKeyAgreementPayload silc_key_agreement_payload_parse(SilcBuffer buffer)
+{
+ SilcKeyAgreementPayload new;
+ int ret;
+
+ SILC_LOG_DEBUG(("Parsing Key Agreement Payload"));
+
+ new = silc_calloc(1, sizeof(*new));
+
+ /* Parse the payload */
+ ret = silc_buffer_unformat(buffer,
+ SILC_STR_UI16_NSTRING_ALLOC(&new->hostname,
+ &new->hostname_len),
+ SILC_STR_UI_INT(&new->port),
+ SILC_STR_END);
+ if (ret == -1) {
+ silc_free(new);
+ return NULL;
+ }
+
+ return new;
+}
+
+/* Encodes the Key Agreement protocol and returns the encoded buffer */
+
+SilcBuffer silc_key_agreement_payload_encode(char *hostname,
+ uint32 port)
+{
+ SilcBuffer buffer;
+ uint32 len = hostname ? strlen(hostname) : 0;
+
+ SILC_LOG_DEBUG(("Encoding Key Agreement Payload"));
+
+ buffer = silc_buffer_alloc(2 + len + 4);
+ silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
+ silc_buffer_format(buffer,
+ SILC_STR_UI_SHORT(len),
+ SILC_STR_UI_XNSTRING(hostname, len),
+ SILC_STR_UI_INT(port),
+ SILC_STR_END);
+
+ return buffer;
+}
+
+/* Frees the Key Agreement protocol */
+
+void silc_key_agreement_payload_free(SilcKeyAgreementPayload payload)
+{
+ if (payload) {
+ silc_free(payload->hostname);
+ silc_free(payload);
+ }
+}
+
+/* Returns the hostname in the payload */
+
+char *silc_key_agreement_get_hostname(SilcKeyAgreementPayload payload)
+{
+ return payload->hostname;
+}
+
+/* Returns the port in the payload */
+
+uint32 silc_key_agreement_get_port(SilcKeyAgreementPayload payload)
+{
+ return payload->port;
+}