updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 20 Feb 2001 18:13:56 +0000 (18:13 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 20 Feb 2001 18:13:56 +0000 (18:13 +0000)
12 files changed:
CHANGES
apps/silcd/protocol.c
apps/silcd/server.c
apps/silcd/serverconfig.c
doc/draft-riikonen-silc-spec-01.nroff
includes/silcincludes.h
lib/silcclient/client.c
lib/silcclient/protocol.c
lib/silccore/Makefile.am
lib/silccore/silcprotocol.h
lib/silccrypt/silcpkcs.c
lib/silccrypt/silcpkcs.h

diff --git a/CHANGES b/CHANGES
index faf5fa54873d0f6ed1dcc28a8472dd27c14b9500..2894edaf133bee80db2c76e793733a563c27a39b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -25,6 +25,23 @@ Tue Feb 20 14:14:14 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
        * Removed the RNG kludge from lib/silcmath/primegen.c and changed
          it to use the Global RNG API.
 
+       * Defined Authentication Payload into protocol specification that
+         is used during SILC session to authenticate entities.  It is
+         used for example by client to authenticate itself to the server
+         to obtain server operator privileges.
+
+         Implemented this payload into the lib/silccore/silcauth.[ch].
+         Implemented also routines for public key based authentication
+         as the new protocol specification dictates.
+
+         Moved definitions of different authentication methods from
+         lib/silccore/silcprotocol.h into lib/silccore/silcauth.h.
+
+       * Added silc_pkcs_encrypt, silc_pkcs_decrypt, silc_pkcs_sign,
+         silc_pkcs_verify and silc_pkcs_sign_with_hash and
+         silc_pkcs_verify_with_hash functions into the file 
+         lib/silccrypt/silcpkcs.[ch].
+
 Mon Feb 19 19:59:28 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * The client entry's userinfo pointer must be always valid. 
index 991d5a4839210516a34d04eaaf6583a0877a71ee..5ade39a430559dd1dbc8147c96088e8ca5b5bed3 100644 (file)
@@ -605,12 +605,12 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
          
          if (client) {
            switch(client->auth_meth) {
-           case SILC_PROTOCOL_CONN_AUTH_NONE:
+           case SILC_AUTH_NONE:
              /* No authentication required */
              SILC_LOG_DEBUG(("No authentication required"));
              break;
              
-           case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
+           case SILC_AUTH_PASSWORD:
              /* Password authentication */
              SILC_LOG_DEBUG(("Password authentication"));
              ret = silc_server_password_authentication(server, auth_data,
@@ -632,7 +632,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
              return;
              break;
              
-           case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
+           case SILC_AUTH_PUBLIC_KEY:
              /* Public key authentication */
              SILC_LOG_DEBUG(("Public key authentication"));
              ret = silc_server_public_key_authentication(server, 
@@ -684,12 +684,12 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
          
          if (serv) {
            switch(serv->auth_meth) {
-           case SILC_PROTOCOL_CONN_AUTH_NONE:
+           case SILC_AUTH_NONE:
              /* No authentication required */
              SILC_LOG_DEBUG(("No authentication required"));
              break;
              
-           case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
+           case SILC_AUTH_PASSWORD:
              /* Password authentication */
              SILC_LOG_DEBUG(("Password authentication"));
              ret = silc_server_password_authentication(server, auth_data,
@@ -711,7 +711,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
              return;
              break;
              
-           case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
+           case SILC_AUTH_PUBLIC_KEY:
              /* Public key authentication */
              SILC_LOG_DEBUG(("Public key authentication"));
              ret = silc_server_public_key_authentication(server, 
@@ -763,12 +763,12 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
          
          if (serv) {
            switch(serv->auth_meth) {
-           case SILC_PROTOCOL_CONN_AUTH_NONE:
+           case SILC_AUTH_NONE:
              /* No authentication required */
              SILC_LOG_DEBUG(("No authentication required"));
              break;
              
-           case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
+           case SILC_AUTH_PASSWORD:
              /* Password authentication */
              SILC_LOG_DEBUG(("Password authentication"));
              ret = silc_server_password_authentication(server, auth_data,
@@ -790,7 +790,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
              return;
              break;
              
-           case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
+           case SILC_AUTH_PUBLIC_KEY:
              /* Public key authentication */
              SILC_LOG_DEBUG(("Public key authentication"));
              ret = silc_server_public_key_authentication(server, 
@@ -852,11 +852,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        unsigned int auth_data_len = 0;
        
        switch(ctx->auth_meth) {
-       case SILC_PROTOCOL_CONN_AUTH_NONE:
+       case SILC_AUTH_NONE:
          /* No authentication required */
          break;
          
-       case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
+       case SILC_AUTH_PASSWORD:
          /* Password authentication */
          if (ctx->auth_data && ctx->auth_data_len) {
            auth_data = ctx->auth_data;
@@ -869,7 +869,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
 
          break;
          
-       case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
+       case SILC_AUTH_PUBLIC_KEY:
          /* Public key authentication */
          /* XXX TODO */
          break;
@@ -911,7 +911,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        */
       unsigned char ok[4];
 
-      SILC_PUT32_MSB(SILC_CONN_AUTH_OK, ok);
+      SILC_PUT32_MSB(SILC_AUTH_OK, ok);
 
       /* Authentication failed */
       silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
@@ -937,7 +937,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        */
       unsigned char error[4];
 
-      SILC_PUT32_MSB(SILC_CONN_AUTH_FAILED, error);
+      SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
 
       /* Authentication failed */
       silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
index a41add7d9158fade694bdf2f45e16e1d058c7233..b0d10ecdbd6a60cdb9417fc1a3b4e705925b2b86 100644 (file)
@@ -718,7 +718,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
   proto_ctx->dest_id = ctx->dest_id;
 
   /* Resolve the authentication method used in this connection */
-  proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+  proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
   if (server->config->routers) {
     SilcConfigServerSectionServerConnection *conn = NULL;
 
index 4e42c44557d3305c07e706303080e4965a17731e..aed9017711d6eb0bac301f3aaae76c557b30ed49 100644 (file)
@@ -766,10 +766,10 @@ int silc_config_server_parse_lines(SilcConfigServer config,
        }
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
-         config->clients->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+         config->clients->auth_meth = SILC_AUTH_PASSWORD;
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
-         config->clients->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+         config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
 
        silc_free(tmp);
       }
@@ -829,10 +829,10 @@ int silc_config_server_parse_lines(SilcConfigServer config,
        }
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
-         config->servers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+         config->servers->auth_meth = SILC_AUTH_PASSWORD;
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
-         config->servers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+         config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
 
        silc_free(tmp);
       }
@@ -894,10 +894,10 @@ int silc_config_server_parse_lines(SilcConfigServer config,
        }
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
-         config->routers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+         config->routers->auth_meth = SILC_AUTH_PASSWORD;
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
-         config->routers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+         config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
 
        silc_free(tmp);
       }
@@ -970,10 +970,10 @@ int silc_config_server_parse_lines(SilcConfigServer config,
        }
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
-         config->admins->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+         config->admins->auth_meth = SILC_AUTH_PASSWORD;
 
        if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
-         config->admins->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+         config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
 
        silc_free(tmp);
       }
index 7428a40e4baf413a31c6e7f39627f3d5b005407c..da521280f3eec8696c4f93f8954f51ccb68eea2a 100644 (file)
@@ -1029,6 +1029,92 @@ may be based on passphrase (pre-shared-secret) or public key.  The
 connection authentication protocol is described in detail in [SILC3].
 
 
+.ti 0
+3.9.1 Authentication Payload
+
+Authentication payload is used separately from the SKE and the Connection
+authentication protocol.  It is used during the session to authenticate
+with the remote.  For example, the client can authenticate itself to the
+server to be server operator.  In this case, Authentication Payload is
+used.
+
+The format of the Authentication Payload is as follows:
+
+
+.in 5
+.nf
+                     1                   2                   3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|        Payload Length         |     Authentication Method     |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|      Public Data Length       |                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+|                                                               |
+~                           Public Data                         ~
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|   Authentication Data Length  |                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+|                                                               |
+~                       Authentication Data                     ~
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|
+.in 3
+.ce
+Figure 5:  Authentication Payload
+
+
+.in 6
+o Payload Length (2 bytes) - Length of the entire payload.
+
+o Authentication Type (2) - The method of the authentication.
+  The authentication methods are defined in [SILC2] in the
+  Connection Auth Request Payload.  The NONE authentication
+  method is not recommended.
+
+o Public Data Length (2 bytes) - Indicates the length of
+  the Public Data field.
+
+o Public Data (variable length) - This is defined only if
+  the authentication method is public key.  If it is any other
+  this field does not exist and the Public Data Length field
+  is set to zero (0).
+
+  When the authentication method is public key this includes
+  128 to 4096 bytes of non-zero random data that is used in
+  the signature process, described subsequently.
+
+o Authentication Data Length (2 bytes) - Indicates the
+  length of the Authentication Data field.
+
+o Authentication Data (variable length) - Authentication 
+  method dependent authentication data.
+.in 3
+
+
+If the authentication method is password based, the Authentication
+Data field includes the plaintext password.  It is safe to send
+plaintext password since the entire payload is encrypted.
+
+If the authentication method is public key based (or certificate)
+the Authentication Data is computed as follows:
+
+  HASH = hash(random bytes | public key (or certificate));
+  Authentication Data = sign(HASH);
+
+The hash() and sign() are the hash funtion and the public key cryptography
+function selected in the SKE protocol.  The public key is SILC style
+public key unless certificates are used.  The random bytes are non-zero
+random bytes of length between 128 and 4096 bytes, and will be included
+into the Public Data field as is.  The receiver will compute the signature
+using the random data received in the payload and the public key (or
+certificate) received in the SKE protocol.  After computing the receiver
+must verify the signature.  In this case also, the entire payload is
+encrypted.
+
+
 .ti 0
 3.10 Algorithms
 
index 9685d8ec5bc58925da478bd66809e6013984d248..13bae760d6492ab09a3f3a4a8942bd7f8f1b6f36 100644 (file)
 #include "silcpacket.h"
 #include "silcnotify.h"
 #include "silcmode.h"
+#include "silcauth.h"
 
 /* TRQ (SilcList API and SilcDList API) */
 #include "silclist.h"
index 9b34079ac05b5600c51e3c78a828f32a8cf318d3..928d4c188cf72c41b2e7f989c06a98bc11f1e6cd 100644 (file)
@@ -416,7 +416,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
                                    &proto_ctx->auth_data_len))
     {
       /* XXX do AUTH_REQUEST resolcing with server */
-      proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
+      proto_ctx->auth_meth = SILC_AUTH_NONE;
     }
 
   /* Free old protocol as it is finished now */
index fe7a3544a6299a747a3529a83f9d008b743982a6..4444a8b31df389d27d28f6e8ac60831f70b990d7 100644 (file)
@@ -433,11 +433,11 @@ SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
       unsigned int auth_data_len = 0;
 
       switch(ctx->auth_meth) {
-      case SILC_PROTOCOL_CONN_AUTH_NONE:
+      case SILC_AUTH_NONE:
        /* No authentication required */
        break;
 
-      case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
+      case SILC_AUTH_PASSWORD:
        /* Password authentication */
        if (ctx->auth_data && ctx->auth_data_len) {
          auth_data = ctx->auth_data;
@@ -452,7 +452,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
        auth_data_len = strlen(auth_data);
        break;
 
-      case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
+      case SILC_AUTH_PUBLIC_KEY:
        /* XXX */
        break;
       }
@@ -504,7 +504,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
        */
       unsigned char error[4];
 
-      SILC_PUT32_MSB(SILC_CONN_AUTH_FAILED, error);
+      SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
 
       /* Error in protocol. Send FAILURE packet. Although I don't think
         this could ever happen on client side. */
index eda260a808785c507f83956afa4e669a575207d6..fb03c6a6806d3d739a441f746cc640b17130a32d 100644 (file)
@@ -30,7 +30,8 @@ libsilccore_a_SOURCES = \
        silcsockconn.c \
        silcpayload.c \
        silcnotify.c \
-       silcmode.c
+       silcmode.c \
+       silcauth.c
 
 EXTRA_DIST = *.h
 
index 6d5ef0b529d89455536b9fea1c5bf02ab06feb4c..8336745d6ba98e8975c52e121bb81c80546bdcb1 100644 (file)
@@ -35,16 +35,6 @@ typedef unsigned char SilcProtocolState;
 #define SILC_PROTOCOL_STATE_FAILURE 253         /* Received failure from remote */
 #define SILC_PROTOCOL_STATE_ERROR 254    /* Local error at our end */
 
-/* Connection Authentication protocols' authentication methods */
-#define SILC_PROTOCOL_CONN_AUTH_NONE 0
-#define SILC_PROTOCOL_CONN_AUTH_PASSWORD 1
-#define SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY 2
-
-/* XXX These don't belong here really! */
-/* Connection authentication protocol status message */
-#define SILC_CONN_AUTH_OK 0
-#define SILC_CONN_AUTH_FAILED 1
-
 /* Type definition for above auth methods */
 typedef unsigned char SilcProtocolAuthMeth;
 
index c193fc87c2d96116c86daf678db6f1fe305e9eb7..c25e99ec9329253eb2f535e862145253059b92bf 100644 (file)
@@ -182,6 +182,82 @@ int silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
   return pkcs->pkcs->set_private_key(pkcs->context, prv, prv_len);
 }
 
+/* Encrypts */
+
+int silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, unsigned int src_len,
+                     unsigned char *dst, unsigned int *dst_len)
+{
+  return pkcs->pkcs->encrypt(pkcs->context, src, src_len, dst, dst_len);
+}
+
+/* Decrypts */
+
+int silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, unsigned int src_len,
+                     unsigned char *dst, unsigned int *dst_len)
+{
+  return pkcs->pkcs->decrypt(pkcs->context, src, src_len, dst, dst_len);
+}
+
+/* Generates signature */
+
+int silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, unsigned int src_len,
+                  unsigned char *dst, unsigned int *dst_len)
+{
+  return pkcs->pkcs->sign(pkcs->context, src, src_len, dst, dst_len);
+}
+
+/* Verifies signature */
+
+int silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature, 
+                    unsigned int signature_len, unsigned char *data, 
+                    unsigned int data_len)
+{
+  return pkcs->pkcs->verify(pkcs->context, signature, signature_len, 
+                           data, data_len);
+}
+
+/* Generates signature with hash. The hash is signed. */
+
+int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
+                            unsigned char *src, unsigned int src_len,
+                            unsigned char *dst, unsigned int *dst_len)
+{
+  unsigned char hashr[32];
+  unsigned int hash_len;
+  int ret;
+
+  silc_hash_make(hash, src, src_len, hashr);
+  hash_len = hash->hash->hash_len;
+
+  ret = pkcs->pkcs->sign(pkcs->context, hashr, hash_len, dst, dst_len);
+  memset(hashr, 0, sizeof(hashr));
+
+  return ret;
+}
+
+/* Verifies signature with hash. The `data' is hashed and verified against
+   the `signature'. */
+
+int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash, 
+                              unsigned char *signature, 
+                              unsigned int signature_len, 
+                              unsigned char *data, 
+                              unsigned int data_len)
+{
+  unsigned char hashr[32];
+  unsigned int hash_len;
+  int ret;
+
+  silc_hash_make(hash, data, data_len, hashr);
+  hash_len = hash->hash->hash_len;
+
+  ret = pkcs->pkcs->verify(pkcs->context, signature, signature_len, 
+                          hashr, hash_len);
+  memset(hashr, 0, sizeof(hashr));
+
+  return ret;
+}
+
 /* Encodes and returns SILC public key identifier. If some of the 
    arguments is NULL those are not encoded into the identifier string.
    Protocol says that at least username and host must be provided. */
index c726cfa80c2e81c45a9ed2d78153458710fb8c97..9614bb8d4927bd994ef73ccce324700603baf2bf 100644 (file)
@@ -178,6 +178,23 @@ int silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
 int silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key);
 int silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
                                   unsigned int prv_len);
+int silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, unsigned int src_len,
+                     unsigned char *dst, unsigned int *dst_len);
+int silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, unsigned int src_len,
+                     unsigned char *dst, unsigned int *dst_len);
+int silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, unsigned int src_len,
+                  unsigned char *dst, unsigned int *dst_len);
+int silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature, 
+                    unsigned int signature_len, unsigned char *data, 
+                    unsigned int data_len);
+int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
+                            unsigned char *src, unsigned int src_len,
+                            unsigned char *dst, unsigned int *dst_len);
+int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash, 
+                              unsigned char *signature, 
+                              unsigned int signature_len, 
+                              unsigned char *data, 
+                              unsigned int data_len);
 char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
                                  char *email, char *org, char *country);
 SilcPublicKey silc_pkcs_public_key_alloc(char *name, char *identifier,