From: Pekka Riikonen Date: Tue, 20 Feb 2001 18:13:56 +0000 (+0000) Subject: updates. X-Git-Tag: SILC.0.1~197 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=3adc9df4c346c5d1cb3cc500f2be8293edff8bec updates. --- diff --git a/CHANGES b/CHANGES index faf5fa54..2894edaf 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,23 @@ Tue Feb 20 14:14:14 EET 2001 Pekka Riikonen * 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 * The client entry's userinfo pointer must be always valid. diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index 991d5a48..5ade39a4 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -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, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index a41add7d..b0d10ecd 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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; diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 4e42c445..aed90177 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -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); } diff --git a/doc/draft-riikonen-silc-spec-01.nroff b/doc/draft-riikonen-silc-spec-01.nroff index 7428a40e..da521280 100644 --- a/doc/draft-riikonen-silc-spec-01.nroff +++ b/doc/draft-riikonen-silc-spec-01.nroff @@ -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 diff --git a/includes/silcincludes.h b/includes/silcincludes.h index 9685d8ec..13bae760 100644 --- a/includes/silcincludes.h +++ b/includes/silcincludes.h @@ -161,6 +161,7 @@ #include "silcpacket.h" #include "silcnotify.h" #include "silcmode.h" +#include "silcauth.h" /* TRQ (SilcList API and SilcDList API) */ #include "silclist.h" diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 9b34079a..928d4c18 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -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 */ diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index fe7a3544..4444a8b3 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -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. */ diff --git a/lib/silccore/Makefile.am b/lib/silccore/Makefile.am index eda260a8..fb03c6a6 100644 --- a/lib/silccore/Makefile.am +++ b/lib/silccore/Makefile.am @@ -30,7 +30,8 @@ libsilccore_a_SOURCES = \ silcsockconn.c \ silcpayload.c \ silcnotify.c \ - silcmode.c + silcmode.c \ + silcauth.c EXTRA_DIST = *.h diff --git a/lib/silccore/silcprotocol.h b/lib/silccore/silcprotocol.h index 6d5ef0b5..8336745d 100644 --- a/lib/silccore/silcprotocol.h +++ b/lib/silccore/silcprotocol.h @@ -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; diff --git a/lib/silccrypt/silcpkcs.c b/lib/silccrypt/silcpkcs.c index c193fc87..c25e99ec 100644 --- a/lib/silccrypt/silcpkcs.c +++ b/lib/silccrypt/silcpkcs.c @@ -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. */ diff --git a/lib/silccrypt/silcpkcs.h b/lib/silccrypt/silcpkcs.h index c726cfa8..9614bb8d 100644 --- a/lib/silccrypt/silcpkcs.h +++ b/lib/silccrypt/silcpkcs.h @@ -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,