From b785014a15f18a77dd348b7d696983f08f0b68a3 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Sat, 17 Sep 2011 20:05:58 +0200 Subject: crypt: Rename to packet_crypt. --- include/libssh/packet.h | 16 ++++ include/libssh/poll.h | 2 + include/libssh/priv.h | 16 ---- src/CMakeLists.txt | 2 +- src/crypt.c | 197 ------------------------------------------------ src/packet_crypt.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 216 insertions(+), 214 deletions(-) delete mode 100644 src/crypt.c create mode 100644 src/packet_crypt.c diff --git a/include/libssh/packet.h b/include/libssh/packet.h index 414c0ac..22138e4 100644 --- a/include/libssh/packet.h +++ b/include/libssh/packet.h @@ -22,6 +22,8 @@ #ifndef PACKET_H_ #define PACKET_H_ +struct ssh_socket_struct; + /* this structure should go someday */ typedef struct packet_struct { int valid; @@ -58,5 +60,19 @@ int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum); int ssh_packet_parse_type(ssh_session session); //int packet_flush(ssh_session session, int enforce_blocking); +int ssh_packet_socket_callback(const void *data, size_t len, void *user); +void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s); +void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks); +void ssh_packet_set_default_callbacks(ssh_session session); +void ssh_packet_process(ssh_session session, uint8_t type); + +/* PACKET CRYPT */ +uint32_t packet_decrypt_len(ssh_session session, char *crypted); +int packet_decrypt(ssh_session session, void *packet, unsigned int len); +unsigned char *packet_encrypt(ssh_session session, + void *packet, + unsigned int len); +int packet_hmac_verify(ssh_session session,ssh_buffer buffer, + unsigned char *mac); #endif /* PACKET_H_ */ diff --git a/include/libssh/poll.h b/include/libssh/poll.h index 88a16a1..6c5dbbe 100644 --- a/include/libssh/poll.h +++ b/include/libssh/poll.h @@ -21,6 +21,7 @@ #ifndef POLL_H_ #define POLL_H_ + #include "config.h" #ifdef HAVE_POLL @@ -135,6 +136,7 @@ typedef struct ssh_poll_handle_struct *ssh_poll_handle; typedef int (*ssh_poll_callback)(ssh_poll_handle p, socket_t fd, int revents, void *userdata); +struct ssh_socket_struct; ssh_poll_handle ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata); diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 522f56b..44ec43d 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -184,22 +184,6 @@ SSH_PACKET_CALLBACK(ssh_packet_dh_reply); SSH_PACKET_CALLBACK(ssh_packet_newkeys); SSH_PACKET_CALLBACK(ssh_packet_service_accept); -/* in crypt.c */ -uint32_t packet_decrypt_len(ssh_session session,char *crypted); -int packet_decrypt(ssh_session session, void *packet,unsigned int len); -unsigned char *packet_encrypt(ssh_session session,void *packet,unsigned int len); - /* it returns the hmac buffer if exists*/ -struct ssh_poll_handle_struct; - -int packet_hmac_verify(ssh_session session,ssh_buffer buffer,unsigned char *mac); - -struct ssh_socket_struct; - -int ssh_packet_socket_callback(const void *data, size_t len, void *user); -void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s); -void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks); -void ssh_packet_set_default_callbacks(ssh_session session); -void ssh_packet_process(ssh_session session, uint8_t type); /* connect.c */ socket_t ssh_connect_host(ssh_session session, const char *host,const char *bind_addr, int port, long timeout, long usec); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1504b76..d783e7a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,7 +82,6 @@ set(libssh_SRCS client.c config.c connect.c - crypt.c dh.c ecdh.c error.c @@ -99,6 +98,7 @@ set(libssh_SRCS misc.c options.c packet.c + packet_crypt.c pcap.c pki.c poll.c diff --git a/src/crypt.c b/src/crypt.c deleted file mode 100644 index 5acb126..0000000 --- a/src/crypt.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * crypt.c - blowfish-cbc code - * - * This file is part of the SSH Library - * - * Copyright (c) 2003 by Aris Adamantiadis - * - * The SSH Library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * The SSH Library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include -#include -#include - -#ifndef _WIN32 -#include -#endif - -#ifdef OPENSSL_CRYPTO -#include -#include -#include -#endif - -#include "libssh/priv.h" -#include "libssh/session.h" -#include "libssh/wrapper.h" -#include "libssh/crypto.h" -#include "libssh/buffer.h" - -uint32_t packet_decrypt_len(ssh_session session, char *crypted){ - uint32_t decrypted; - - if (session->current_crypto) { - if (packet_decrypt(session, crypted, - session->current_crypto->in_cipher->blocksize) < 0) { - return 0; - } - } - - memcpy(&decrypted,crypted,sizeof(decrypted)); - ssh_log(session, SSH_LOG_PACKET, - "Packet size decrypted: %lu (0x%lx)", - (long unsigned int) ntohl(decrypted), - (long unsigned int) ntohl(decrypted)); - return ntohl(decrypted); -} - -int packet_decrypt(ssh_session session, void *data,uint32_t len) { - struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher; - char *out = NULL; - if(len % session->current_crypto->in_cipher->blocksize != 0){ - ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); - return SSH_ERROR; - } - out = malloc(len); - if (out == NULL) { - return -1; - } - - ssh_log(session,SSH_LOG_PACKET, "Decrypting %d bytes", len); - - - if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey, - session->current_crypto->decryptIV) < 0) { - SAFE_FREE(out); - return -1; - } - crypto->cbc_decrypt(crypto,data,out,len); - - memcpy(data,out,len); - memset(out,0,len); - - SAFE_FREE(out); - return 0; -} - -unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) { - struct ssh_cipher_struct *crypto = NULL; - HMACCTX ctx = NULL; - char *out = NULL; - unsigned int finallen; - uint32_t seq; - - if (!session->current_crypto) { - return NULL; /* nothing to do here */ - } - if(len % session->current_crypto->in_cipher->blocksize != 0){ - ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); - return NULL; - } - out = malloc(len); - if (out == NULL) { - return NULL; - } - - seq = ntohl(session->send_seq); - crypto = session->current_crypto->out_cipher; - - ssh_log(session, SSH_LOG_PACKET, - "Encrypting packet with seq num: %d, len: %d", - session->send_seq,len); - - if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey, - session->current_crypto->encryptIV) < 0) { - SAFE_FREE(out); - return NULL; - } - - if (session->version == 2) { - ctx = hmac_init(session->current_crypto->encryptMAC,20,SSH_HMAC_SHA1); - if (ctx == NULL) { - SAFE_FREE(out); - return NULL; - } - hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t)); - hmac_update(ctx,data,len); - hmac_final(ctx,session->current_crypto->hmacbuf,&finallen); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("mac: ",data,len); - if (finallen != 20) { - printf("Final len is %d\n",finallen); - } - ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20); -#endif - } - - crypto->cbc_encrypt(crypto, data, out, len); - - memcpy(data, out, len); - memset(out, 0, len); - SAFE_FREE(out); - - if (session->version == 2) { - return session->current_crypto->hmacbuf; - } - - return NULL; -} - -/** - * @internal - * - * @brief Verify the hmac of a packet - * - * @param session The session to use. - * @param buffer The buffer to verify the hmac from. - * @param mac The mac to compare with the hmac. - * - * @return 0 if hmac and mac are equal, < 0 if not or an error - * occurred. - */ -int packet_hmac_verify(ssh_session session, ssh_buffer buffer, - unsigned char *mac) { - unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0}; - HMACCTX ctx; - unsigned int len; - uint32_t seq; - - ctx = hmac_init(session->current_crypto->decryptMAC, 20, SSH_HMAC_SHA1); - if (ctx == NULL) { - return -1; - } - - seq = htonl(session->recv_seq); - - hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t)); - hmac_update(ctx, buffer_get_rest(buffer), buffer_get_rest_len(buffer)); - hmac_final(ctx, hmacbuf, &len); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("received mac",mac,len); - ssh_print_hexa("Computed mac",hmacbuf,len); - ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t)); -#endif - if (memcmp(mac, hmacbuf, len) == 0) { - return 0; - } - - return -1; -} - -/* vim: set ts=2 sw=2 et cindent: */ diff --git a/src/packet_crypt.c b/src/packet_crypt.c new file mode 100644 index 0000000..6f78138 --- /dev/null +++ b/src/packet_crypt.c @@ -0,0 +1,197 @@ +/* + * crypt.c - blowfish-cbc code + * + * This file is part of the SSH Library + * + * Copyright (c) 2003 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "config.h" +#include +#include +#include + +#ifndef _WIN32 +#include +#endif + +#ifdef OPENSSL_CRYPTO +#include +#include +#include +#endif + +#include "libssh/priv.h" +#include "libssh/session.h" +#include "libssh/wrapper.h" +#include "libssh/crypto.h" +#include "libssh/buffer.h" + +uint32_t packet_decrypt_len(ssh_session session, char *crypted){ + uint32_t decrypted; + + if (session->current_crypto) { + if (packet_decrypt(session, crypted, + session->current_crypto->in_cipher->blocksize) < 0) { + return 0; + } + } + + memcpy(&decrypted,crypted,sizeof(decrypted)); + ssh_log(session, SSH_LOG_PACKET, + "Packet size decrypted: %lu (0x%lx)", + (long unsigned int) ntohl(decrypted), + (long unsigned int) ntohl(decrypted)); + return ntohl(decrypted); +} + +int packet_decrypt(ssh_session session, void *data,uint32_t len) { + struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher; + char *out = NULL; + if(len % session->current_crypto->in_cipher->blocksize != 0){ + ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); + return SSH_ERROR; + } + out = malloc(len); + if (out == NULL) { + return -1; + } + + ssh_log(session,SSH_LOG_PACKET, "Decrypting %d bytes", len); + + + if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey, + session->current_crypto->decryptIV) < 0) { + SAFE_FREE(out); + return -1; + } + crypto->cbc_decrypt(crypto,data,out,len); + + memcpy(data,out,len); + memset(out,0,len); + + SAFE_FREE(out); + return 0; +} + +unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) { + struct ssh_cipher_struct *crypto = NULL; + HMACCTX ctx = NULL; + char *out = NULL; + unsigned int finallen; + uint32_t seq; + + if (!session->current_crypto) { + return NULL; /* nothing to do here */ + } + if(len % session->current_crypto->in_cipher->blocksize != 0){ + ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); + return NULL; + } + out = malloc(len); + if (out == NULL) { + return NULL; + } + + seq = ntohl(session->send_seq); + crypto = session->current_crypto->out_cipher; + + ssh_log(session, SSH_LOG_PACKET, + "Encrypting packet with seq num: %d, len: %d", + session->send_seq,len); + + if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey, + session->current_crypto->encryptIV) < 0) { + SAFE_FREE(out); + return NULL; + } + + if (session->version == 2) { + ctx = hmac_init(session->current_crypto->encryptMAC,20,SSH_HMAC_SHA1); + if (ctx == NULL) { + SAFE_FREE(out); + return NULL; + } + hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t)); + hmac_update(ctx,data,len); + hmac_final(ctx,session->current_crypto->hmacbuf,&finallen); +#ifdef DEBUG_CRYPTO + ssh_print_hexa("mac: ",data,len); + if (finallen != 20) { + printf("Final len is %d\n",finallen); + } + ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20); +#endif + } + + crypto->cbc_encrypt(crypto, data, out, len); + + memcpy(data, out, len); + memset(out, 0, len); + SAFE_FREE(out); + + if (session->version == 2) { + return session->current_crypto->hmacbuf; + } + + return NULL; +} + +/** + * @internal + * + * @brief Verify the hmac of a packet + * + * @param session The session to use. + * @param buffer The buffer to verify the hmac from. + * @param mac The mac to compare with the hmac. + * + * @return 0 if hmac and mac are equal, < 0 if not or an error + * occurred. + */ +int packet_hmac_verify(ssh_session session, ssh_buffer buffer, + unsigned char *mac) { + unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0}; + HMACCTX ctx; + unsigned int len; + uint32_t seq; + + ctx = hmac_init(session->current_crypto->decryptMAC, 20, SSH_HMAC_SHA1); + if (ctx == NULL) { + return -1; + } + + seq = htonl(session->recv_seq); + + hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t)); + hmac_update(ctx, buffer_get_rest(buffer), buffer_get_rest_len(buffer)); + hmac_final(ctx, hmacbuf, &len); + +#ifdef DEBUG_CRYPTO + ssh_print_hexa("received mac",mac,len); + ssh_print_hexa("Computed mac",hmacbuf,len); + ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t)); +#endif + if (memcmp(mac, hmacbuf, len) == 0) { + return 0; + } + + return -1; +} + +/* vim: set ts=2 sw=2 et cindent: */ -- cgit