1
1

added the gcrypt patch (without gcrypt as default library).

still needs tests.


git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@38 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
Aris Adamantiadis 2005-10-04 22:11:19 +00:00
родитель c0525750fd
Коммит 5f7c84f900
29 изменённых файлов: 1338 добавлений и 187 удалений

Просмотреть файл

@ -12,6 +12,9 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <gcrypt.h> header file. */
#undef HAVE_GCRYPT_H
/* Define to 1 if you have the `gethostbyaddr' function. */
#undef HAVE_GETHOSTBYADDR
@ -27,6 +30,9 @@
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `gcrypt' library (-lgcrypt). */
#undef HAVE_LIBGCRYPT
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
@ -55,6 +61,9 @@
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
#undef HAVE_OPENSSL_BLOWFISH_H
/* Define to 1 if you have the <openssl/des.h> header file. */
#undef HAVE_OPENSSL_DES_H
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
#undef HAVE_PAM_PAM_APPL_H

15
configure поставляемый
Просмотреть файл

@ -2786,6 +2786,10 @@ esac
# Checks for libraries.
# AC_CHECK_LIB([gcrypt], [gcry_md_open])
# if test "$ac_cv_lib_gcrypt_gcry_md_open" != yes; then
# AC_CHECK_LIB([crypto], [BN_init])
# fi
echo "$as_me:$LINENO: checking for BN_init in -lcrypto" >&5
echo $ECHO_N "checking for BN_init in -lcrypto... $ECHO_C" >&6
@ -3692,10 +3696,13 @@ done
for ac_header in fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h \
sys/time.h termios.h unistd.h openssl/aes.h openssl/blowfish.h zlib.h \
sys/poll.h stdint.h pty.h pam/pam_appl.h security/pam_appl.h
sys/time.h termios.h unistd.h openssl/aes.h openssl/blowfish.h \
openssl/des.h zlib.h sys/poll.h stdint.h pty.h pam/pam_appl.h \
security/pam_appl.h gcrypt.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@ -5089,8 +5096,8 @@ done
for ac_func in endpwent gethostbyaddr gethostbyname getpass memmove memset cfmakeraw\
select socket strchr strdup strerror strstr poll
for ac_func in endpwent gethostbyaddr gethostbyname getpass memmove memset \
cfmakeraw select socket strchr strdup strerror strstr poll
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5

Просмотреть файл

@ -38,7 +38,11 @@ AC_PROG_RANLIB
AC_C_BIGENDIAN
# Checks for libraries.
AC_CHECK_LIB([crypto], [BN_init])
# AC_CHECK_LIB([gcrypt], [gcry_md_open])
# if test "$ac_cv_lib_gcrypt_gcry_md_open" != yes; then
# AC_CHECK_LIB([crypto], [BN_init])
# fi
AC_CHECK_LIB([crypto],[BN_init])
AC_CHECK_LIB([z], [deflateInit_])
AC_SEARCH_LIBS([hstrerror],[nsl resolv])
AC_SEARCH_LIBS([gethostbyname],[nsl resolv])
@ -46,8 +50,9 @@ AC_SEARCH_LIBS([gethostbyname],[nsl resolv])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h \
sys/time.h termios.h unistd.h openssl/aes.h openssl/blowfish.h zlib.h \
sys/poll.h stdint.h pty.h pam/pam_appl.h security/pam_appl.h])
sys/time.h termios.h unistd.h openssl/aes.h openssl/blowfish.h \
openssl/des.h zlib.h sys/poll.h stdint.h pty.h pam/pam_appl.h \
security/pam_appl.h gcrypt.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@ -60,8 +65,8 @@ AC_FUNC_REALLOC
AC_FUNC_SELECT_ARGTYPES
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([endpwent gethostbyaddr gethostbyname getpass memmove memset cfmakeraw\
select socket strchr strdup strerror strstr poll])
AC_CHECK_FUNCS([endpwent gethostbyaddr gethostbyname getpass memmove memset \
cfmakeraw select socket strchr strdup strerror strstr poll])
AC_CONFIG_FILES([Makefile
libssh/Makefile

Просмотреть файл

@ -33,15 +33,30 @@ MA 02111-1307, USA. */
#ifdef des_set_key
#undef des_set_key
#endif
#ifdef GCRYPT
#include <gcrypt.h>
#endif
struct crypto_struct {
char *name; /* ssh name of the algorithm */
unsigned int blocksize; /* blocksize of the algo */
unsigned int keylen; /* length of the key structure */
#ifdef HAVE_LIBGCRYPT
gcry_cipher_hd_t *key;
#elif defined HAVE_LIBCRYPTO
void *key; /* a key buffer allocated for the algo */
#endif
unsigned int keysize; /* bytes of key used. != keylen */
#ifdef HAVE_LIBGCRYPT
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key, void *IV); /* sets the new key for immediate use */
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key, void *IV);
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len);
#elif defined HAVE_LIBCRYPTO
void (*set_encrypt_key)(struct crypto_struct *cipher, void *key); /* sets the new key for immediate use */
void (*set_decrypt_key)(struct crypto_struct *cipher, void *key);
void (*cbc_encrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
void (*cbc_decrypt)(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV);
#endif
};

Просмотреть файл

@ -20,13 +20,12 @@ MA 02111-1307, USA. */
#ifndef _LIBSSH_H
#define _LIBSSH_H
#include <libssh/config.h>
#include <unistd.h>
#include <sys/select.h> /* for fd_set * */
#include <sys/types.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#define LIBSSH_VERSION "libssh-0.2-dev"
#ifdef __cplusplus
@ -126,7 +125,7 @@ const char *ssh_copyright();
STRING *string_from_char(char *what);
/* it returns the string len in host byte orders. str->size is big endian warning ! */
int string_len(STRING *str);
STRING *string_new(u32 size);
STRING *string_new(unsigned int size);
/* string_fill copies the data in the string. it does NOT check for boundary so allocate enough place with string_new */
void string_fill(STRING *str,void *data,int len);
/* returns a newly allocated char array with the str string and a final nul caracter */
@ -144,11 +143,11 @@ void ssh_print_hexa(char *descr,unsigned char *what, int len);
int ssh_get_random(void *where,int len,int strong);
/* this one can be called by the client to see the hash of the public key before accepting it */
int ssh_get_pubkey_hash(SSH_SESSION *session,char hash[MD5_DIGEST_LEN]);
int ssh_get_pubkey_hash(SSH_SESSION *session,unsigned char hash[MD5_DIGEST_LEN]);
STRING *ssh_get_pubkey(SSH_SESSION *session);
/* in connect.c */
int ssh_fd_poll(SSH_SESSION *session);
int ssh_fd_poll(SSH_SESSION *session,int *write, int *except);
int ssh_select(CHANNEL **channels,CHANNEL **outchannels, int maxfd, fd_set *readfds, struct timeval *timeout);
void publickey_free(PUBLIC_KEY *key);

Просмотреть файл

@ -25,6 +25,7 @@ MA 02111-1307, USA. */
#ifndef _LIBSSH_PRIV_H
#define _LIBSSH_PRIV_H
#include "config.h"
#include "libssh/libssh.h"
/* Debugging constants */
@ -45,25 +46,51 @@ MA 02111-1307, USA. */
#define TYPE_RSA1 3
/* profiling constants. Don't touch them unless you know what you do */
#define OPENSSL_CRYPTO
#ifdef HAVE_LIBCRYPTO
#define OPENSSL_BIGNUMS
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* wrapper things */
#ifdef HAVE_LIBGCRYPT
#include <gcrypt.h>
typedef gcry_md_hd_t SHACTX;
typedef gcry_md_hd_t MD5CTX;
typedef gcry_md_hd_t HMACCTX;
#ifdef MD5_DIGEST_LEN
#undef MD5_DIGEST_LEN
#endif
#define SHA_DIGEST_LEN 20
#define MD5_DIGEST_LEN 16
#define EVP_MAX_MD_SIZE 36
#ifdef OPENSSL_CRYPTO
typedef gcry_mpi_t bignum;
#define bignum_new() gcry_mpi_new(0)
#define bignum_free(num) gcry_mpi_release(num)
#define bignum_set_word(bn,n) gcry_mpi_set_ui(bn,n)
#define bignum_bin2bn(bn,datalen,data) gcry_mpi_scan(data,GCRYMPI_FMT_USG,bn,datalen,NULL)
#define bignum_bn2hex(num,data) gcry_mpi_aprint(GCRYMPI_FMT_HEX,data,NULL,num)
#define bignum_hex2bn(num,datalen,data) gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,datalen,NULL)
#define bignum_rand(num,bits) gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
#define bignum_mod_exp(dest,generator,exp,modulo) gcry_mpi_powm(dest,generator,exp,modulo)
#define bignum_num_bits(num) gcry_mpi_get_nbits(num)
#define bignum_num_bytes(num) ((gcry_mpi_get_nbits(num)+7)/8)
#define bignum_is_bit_set(num,bit) gcry_mpi_test_bit(num,bit)
#define bignum_bn2bin(num,datalen,data) gcry_mpi_print(GCRYMPI_FMT_USG,data,datalen,NULL,num)
#elif defined HAVE_LIBCRYPTO
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/hmac.h>
typedef SHA_CTX SHACTX;
typedef MD5_CTX MD5CTX;
typedef HMAC_CTX HMACCTX;
typedef SHA_CTX* SHACTX;
typedef MD5_CTX* MD5CTX;
typedef HMAC_CTX* HMACCTX;
#ifdef MD5_DIGEST_LEN
#undef MD5_DIGEST_LEN
#endif
@ -91,29 +118,30 @@ typedef BN_CTX* bignum_CTX;
#define bignum_bn2bin(num,ptr) BN_bn2bin(num,ptr)
#endif /* OPENSSL_BIGNUMS */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
/* wrapper.c */
MD5CTX *md5_init(void);
void md5_update(MD5CTX *c, const void *data, unsigned long len);
void md5_final(unsigned char *md,MD5CTX *c);
SHACTX *sha1_init(void);
void sha1_update(SHACTX *c, const void *data, unsigned long len);
void sha1_final(unsigned char *md,SHACTX *c);
MD5CTX md5_init(void);
void md5_update(MD5CTX c, const void *data, unsigned long len);
void md5_final(unsigned char *md,MD5CTX c);
SHACTX sha1_init(void);
void sha1_update(SHACTX c, const void *data, unsigned long len);
void sha1_final(unsigned char *md,SHACTX c);
void sha1(unsigned char *digest,int len,unsigned char *hash);
#define HMAC_SHA1 1
#define HMAC_MD5 2
HMACCTX *hmac_init(const void *key,int len,int type);
void hmac_update(HMACCTX *c, const void *data, unsigned long len);
void hmac_final(HMACCTX *ctx,unsigned char *hashmacbuf,int *len);
HMACCTX hmac_init(const void *key,int len,int type);
void hmac_update(HMACCTX c, const void *data, unsigned long len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
/* strings and buffers */
/* must be 32 bits number + immediatly our data */
struct string_struct {
u32 size;
char string[MAX_PACKET_LEN];
unsigned char string[MAX_PACKET_LEN];
} __attribute__ ((packed));
@ -132,27 +160,42 @@ typedef struct packet_struct {
} PACKET;
typedef struct kex_struct {
char cookie[16];
unsigned char cookie[16];
char **methods;
} KEX;
struct public_key_struct {
int type;
char *type_c; /* Don't free it ! it is static */
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa_pub;
gcry_sexp_t rsa_pub;
#elif HAVE_LIBCRYPTO
DSA *dsa_pub;
RSA *rsa_pub;
#endif
};
struct private_key_struct {
int type;
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa_priv;
gcry_sexp_t rsa_priv;
#elif defined HAVE_LIBCRYPTO
DSA *dsa_priv;
RSA *rsa_priv;
#endif
};
typedef struct signature_struct {
int type;
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa_sign;
gcry_sexp_t rsa_sign;
#elif defined HAVE_LIBCRYPTO
DSA_SIG *dsa_sign;
STRING *rsa_sign;
#endif
} SIGNATURE;
struct ssh_options_struct {
@ -183,17 +226,17 @@ struct ssh_options_struct {
typedef struct ssh_crypto_struct {
bignum e,f,x,k,y;
char session_id[SHA_DIGEST_LEN];
unsigned char session_id[SHA_DIGEST_LEN];
char encryptIV[SHA_DIGEST_LEN*2];
char decryptIV[SHA_DIGEST_LEN*2];
unsigned char encryptIV[SHA_DIGEST_LEN*2];
unsigned char decryptIV[SHA_DIGEST_LEN*2];
char decryptkey[SHA_DIGEST_LEN*2];
char encryptkey[SHA_DIGEST_LEN*2];
unsigned char decryptkey[SHA_DIGEST_LEN*2];
unsigned char encryptkey[SHA_DIGEST_LEN*2];
char encryptMAC[SHA_DIGEST_LEN];
char decryptMAC[SHA_DIGEST_LEN];
char hmacbuf[EVP_MAX_MD_SIZE];
unsigned char encryptMAC[SHA_DIGEST_LEN];
unsigned char decryptMAC[SHA_DIGEST_LEN];
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
struct crypto_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
STRING *server_pubkey;
char *server_pubkey_type;
@ -302,7 +345,7 @@ struct ssh_kbdint {
char *name;
char *instruction;
char **prompts;
char *echo; /* bool array */
unsigned char *echo; /* bool array */
char **answers;
};
/* session.c */
@ -320,6 +363,7 @@ void ssh_set_error(void *error,int code,char *descr,...);
/* in dh.c */
/* DH key generation */
void dh_generate_e(SSH_SESSION *session);
void ssh_print_bignum(char *which,bignum num);
void dh_generate_x(SSH_SESSION *session);
void dh_generate_y(SSH_SESSION *session);
void dh_generate_f(SSH_SESSION *session);
@ -343,9 +387,9 @@ STRING *make_bignum_string(bignum num);
/* in crypt.c */
u32 packet_decrypt_len(SSH_SESSION *session,char *crypted);
int packet_decrypt(SSH_SESSION *session, void *packet,unsigned int len);
char *packet_encrypt(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*/
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,char *mac);
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,unsigned char *mac);
/* in packet.c */
void packet_clear_out(SSH_SESSION *session);
@ -434,7 +478,7 @@ int buffer_pass_bytes(BUFFER *buffer, int len);
/* in base64.c */
BUFFER *base64_to_bin(char *source);
char *bin_to_base64(unsigned char *source, int len);
unsigned char *bin_to_base64(unsigned char *source, int len);
/* gzip.c */
int compress_buffer(SSH_SESSION *session,BUFFER *buf);
@ -445,7 +489,6 @@ int crypt_set_algorithms(SSH_SESSION *);
int crypt_set_algorithms_server(SSH_SESSION *session);
CRYPTO *crypto_new();
void crypto_free(CRYPTO *crypto);
bignum bignum_new();
/* crc32.c */
u32 ssh_crc32(char *buffer, int len);

Просмотреть файл

@ -21,6 +21,8 @@ MA 02111-1307, USA. */
#include "libssh/priv.h"
#include "libssh/ssh2.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>

Просмотреть файл

@ -23,6 +23,7 @@ MA 02111-1307, USA. */
#include "libssh/ssh1.h"
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
/*
static void burn(char *ptr){
@ -187,7 +188,7 @@ int ssh_userauth1_password(SSH_SESSION *session,char *username,char *password){
*/
password_s=string_new(128);
ssh_get_random(password_s->string,128,0);
strcpy(password_s->string,password);
strcpy((char *)password_s->string,password);
}
packet_clear_out(session);

Просмотреть файл

@ -193,10 +193,10 @@ static void _bin_to_base64(unsigned char *dest, unsigned char source[3], int len
}
}
char *bin_to_base64(unsigned char *source, int len){
unsigned char *bin_to_base64(unsigned char *source, int len){
int flen=len + (3 - (len %3)); /* round to upper 3 multiple */
char *buffer;
char *ptr;
unsigned char *buffer;
unsigned char *ptr;
flen=(4 * flen)/3 + 1 ;
ptr=buffer=malloc(flen);
while(len>0){

Просмотреть файл

@ -150,7 +150,7 @@ STRING *buffer_get_ssh_string(BUFFER *buffer){
hostlen=ntohl(stringlen);
/* verify if there is enough space in buffer to get it */
if(buffer->pos+hostlen>buffer->used)
return 0; /* it is indeed */
return NULL; /* it is indeed */
str=string_new(hostlen);
if(buffer_get_data(buffer,str->string,hostlen)!=hostlen){
ssh_say(0,"buffer_get_ssh_string: oddish : second test failed when first was successful. len=%d",hostlen);

Просмотреть файл

@ -661,18 +661,20 @@ int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr){
/* returns the number of bytes available, 0 if nothing is currently available, -1 if error */
int channel_poll(CHANNEL *channel, int is_stderr){
BUFFER *buffer;
int r=0,w=0,err=0;
if(is_stderr)
buffer=channel->stderr_buffer;
else
buffer=channel->stdout_buffer;
while(buffer_get_rest_len(buffer)==0 && !channel->remote_eof){
if(ssh_fd_poll(channel->session)){
if(packet_read(channel->session)||packet_translate(channel->session))
return -1;
packet_parse(channel->session);
} else
return 0; /* nothing is available has said fd_poll */
r=ssh_fd_poll(channel->session,&w,&err);
if(r<=0)
return r; // error or no data available
/* if an exception happened, it will be trapped by packet_read() */
if(packet_read(channel->session)||packet_translate(channel->session))
return -1;
packet_parse(channel->session);
}
if(channel->remote_eof)
return 1;
@ -700,4 +702,18 @@ int channel_read_nonblocking(CHANNEL *channel, char *dest, int len, int is_stder
SSH_SESSION *channel_get_session(CHANNEL *channel){
return channel->session;
}
/*
int channel_select(CHANNEL *readchans, CHANNEL *writechans, CHANNEL *exceptchans, struct
timeval * timeout){
fd_set rset;
fd_set wset;
fd_set eset;
int rmax=-1, wmax=-1, emax=-1; // nothing to do with the low quality editor :)
int i;
FD_ZERO(rset);
FD_ZERO(wset);
FD_ZERO(eset);
for(i=0;readchans[i];++i){
if(!readchans[i].
*/

Просмотреть файл

@ -26,6 +26,7 @@ MA 02111-1307, USA. */
#include <netdb.h>
#include "libssh/priv.h"
#include "libssh/ssh2.h"
extern int connections;
#define set_status(opt,status) do {\
if (opt->connect_status_function) \
@ -277,6 +278,12 @@ void ssh_disconnect(SSH_SESSION *session){
}
session->alive=0;
ssh_cleanup(session);
if (!--connections)
#ifdef HAVE_LIBGCRYPT
gcry_control(GCRYCTL_TERM_SECMEM);
#elif defined HAVE_LIBCRYPTO
EVP_cleanup();
#endif
}
const char *ssh_copyright(){

Просмотреть файл

@ -32,15 +32,16 @@ MA 02111-1307, USA. */
#include <netinet/in.h>
#include <fcntl.h>
#include "libssh/priv.h"
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#ifndef HAVE_GETHOSTBYNAME
#ifndef HAVE_GETHOSTBYADDR
#error "your system doesn't have gethostbyname nor gethostbyaddr"
#endif
#endif
#ifndef HAVE_SELECT
#error "Your system must have select()"
#endif
static void sock_set_nonblocking(int sock) {
fcntl(sock,F_SETFL,O_NONBLOCK);
}
@ -118,7 +119,7 @@ int ssh_connect_host(SSH_SESSION *session, const char *host, const char
struct timeval to;
fd_set set;
int ret=0;
int len=sizeof(ret);
unsigned int len=sizeof(ret);
to.tv_sec=timeout;
to.tv_usec=usec;
sock_set_nonblocking(s);
@ -157,46 +158,45 @@ int ssh_connect_host(SSH_SESSION *session, const char *host, const char
return s;
}
/* returns 1 if bytes are available on the stream, 0 instead */
int ssh_fd_poll(SSH_SESSION *session){
#ifdef HAVE_POLL
struct pollfd fdset;
#else
/* returns 1 if bytes are available to read on the stream, 0 instead */
/* -1 on select() error. */
int ssh_fd_poll(SSH_SESSION *session, int *write, int *except){
struct timeval sometime;
fd_set descriptor;
#endif
if(session->data_to_read)
return(session->data_to_read);
#ifdef HAVE_POLL
fdset.fd=session->fd;
fdset.events=POLLHUP|POLLIN|POLLPRI;
fdset.revents=0;
if(poll(&fdset,1,0)==0)
fd_set rdes; // read set
fd_set wdes; // writing set
fd_set edes; // exception set
FD_ZERO(&rdes);
FD_ZERO(&wdes);
FD_ZERO(&edes);
if(!session->alive){
*except=1;
*write=0;
return 0;
if(fdset.revents & (POLLHUP|POLLIN|POLLPRI))
return (session->data_to_read=1);
return 0;
#elif HAVE_SELECT
}
if(!session->data_to_read)
FD_SET(session->fd,&rdes);
if(!session->data_to_write)
FD_SET(session->fd,&wdes);
FD_SET(session->fd,&edes);
/* Set to return immediately (no blocking) */
sometime.tv_sec = 0;
sometime.tv_usec = 0;
/* Set up descriptor */
FD_ZERO(&descriptor);
FD_SET(session->fd, &descriptor);
/* Make the call, and listen for errors */
if (select(session->fd + 1, &descriptor, NULL, NULL, &sometime) < 0) {
if (select(session->fd + 1, &rdes,&wdes,&edes, &sometime) < 0) {
ssh_set_error(NULL,SSH_FATAL, "select: %s", strerror(errno));
return -1;
}
session->data_to_read=FD_ISSET(session->fd,&descriptor);
if(!session->data_to_read)
session->data_to_read=FD_ISSET(session->fd,&rdes);
if(!session->data_to_write)
session->data_to_write=FD_ISSET(session->fd,&wdes);
*except=FD_ISSET(session->fd,&edes);
*write=session->data_to_write;
return session->data_to_read;
#else
#error This system does not have poll() or select(), so ssh_fd_poll() will not work correctly
return 0;
#endif
}
/* this function is a complete wrapper for the select syscall. it does more than wrapping ... */

Просмотреть файл

@ -22,11 +22,14 @@ MA 02111-1307, USA. */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef OPENSSL_CRYPTO
#include <openssl/blowfish.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#endif
#include <netdb.h>
#include "libssh/priv.h"
@ -45,25 +48,34 @@ int packet_decrypt(SSH_SESSION *session, void *data,u32 len){
struct crypto_struct *crypto=session->current_crypto->in_cipher;
char *out=malloc(len);
ssh_say(3,"Decrypting %d bytes data\n",len);
#ifdef HAVE_LIBGCRYPT
crypto->set_decrypt_key(crypto,session->current_crypto->decryptkey,session->current_crypto->decryptIV);
crypto->cbc_decrypt(crypto,data,out,len);
#elif defined HAVE_LIBCRYPTO
crypto->set_decrypt_key(crypto,session->current_crypto->decryptkey);
crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
#endif
memcpy(data,out,len);
memset(out,0,len);
free(out);
return 0;
}
char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){
unsigned char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){
struct crypto_struct *crypto;
HMAC_CTX *ctx;
HMACCTX ctx;
char *out;
int finallen;
unsigned int finallen;
u32 seq=ntohl(session->send_seq);
if(!session->current_crypto)
return NULL; /* nothing to do here */
crypto= session->current_crypto->out_cipher;
ssh_say(3,"seq num = %d, len = %d\n",session->send_seq,len);
#ifdef HAVE_LIBGCRYPT
crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey,session->current_crypto->encryptIV);
#elif defined HAVE_LIBCRYPTO
crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey);
#endif
out=malloc(len);
if(session->version==2){
ctx=hmac_init(session->current_crypto->encryptMAC,20,HMAC_SHA1);
@ -77,7 +89,11 @@ char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){
ssh_print_hexa("packet hmac",session->current_crypto->hmacbuf,20);
#endif
}
#ifdef HAVE_LIBGCRYPT
crypto->cbc_encrypt(crypto,data,out,len);
#elif defined HAVE_LIBCRYPTO
crypto->cbc_encrypt(crypto,data,out,len,session->current_crypto->encryptIV);
#endif
memcpy(data,out,len);
memset(out,0,len);
free(out);
@ -87,10 +103,10 @@ char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){
return NULL;
}
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,char *mac){
HMAC_CTX *ctx;
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,unsigned char *mac){
HMACCTX ctx;
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
int len;
unsigned int len;
u32 seq=htonl(session->recv_seq);
ctx=hmac_init(session->current_crypto->decryptMAC,20,HMAC_SHA1);
hmac_update(ctx,(unsigned char *)&seq,sizeof(u32));

Просмотреть файл

@ -42,9 +42,11 @@ MA 02111-1307, USA. */
#include <netdb.h>
#include "libssh/priv.h"
#ifdef HAVE_LIBCRYPTO
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
#include <string.h>
#include "libssh/crypto.h"
static unsigned char p_value[] = {
@ -65,13 +67,23 @@ static unsigned long g_int = 2 ; /* G is defined as 2 by the ssh2 standards */
static bignum g;
static bignum p;
int connections = 0;
/* maybe it might be enhanced .... */
/* XXX Do it. */
int ssh_get_random(void *where, int len, int strong){
if(strong){
#ifdef HAVE_LIBGCRYPT
gcry_randomize(where,len,GCRY_VERY_STRONG_RANDOM);
return 1;
} else {
gcry_randomize(where,len,GCRY_STRONG_RANDOM);
return 1;
#elif defined HAVE_LIBCRYPTO
return RAND_bytes(where,len);
} else {
return RAND_pseudo_bytes(where,len);
#endif
}
}
@ -79,19 +91,39 @@ int ssh_get_random(void *where, int len, int strong){
void ssh_crypto_init(){
static int init=0;
if(!init){
#ifdef HAVE_LIBGCRYPT
gcry_check_version(NULL);
#endif
g=bignum_new();
bignum_set_word(g,g_int);
#ifdef HAVE_LIBGCRYPT
bignum_bin2bn(p_value,P_LEN,&p);
#elif defined HAVE_LIBCRYPTO
p=bignum_new();
bignum_bin2bn(p_value,P_LEN,p);
#endif
init++;
}
if (!connections++){
#ifdef HAVE_LIBGCRYPT
gcry_control(GCRYCTL_INIT_SECMEM,524288,0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0);
#elif defined HAVE_LIBCRYPTO
OpenSSL_add_all_algorithms();
#endif
}
}
/* prints the bignum on stderr */
void ssh_print_bignum(char *which,bignum num){
#ifdef HAVE_LIBGCRYPT
unsigned char *hex;
bignum_bn2hex(num,&hex);
#elif defined HAVE_LIBCRYPTO
char *hex;
fprintf(stderr,"%s value: ",which);
hex=bignum_bn2hex(num);
#endif
fprintf(stderr,"%s value: ",which);
fprintf(stderr,"%s\n",hex);
free(hex);
}
@ -111,7 +143,11 @@ void ssh_print_hexa(char *descr,unsigned char *what, int len){
void dh_generate_x(SSH_SESSION *session){
session->next_crypto->x=bignum_new();
#ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->x,128);
#elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->x,128,0,-1);
#endif
/* not harder than this */
#ifdef DEBUG_CRYPTO
ssh_print_bignum("x",session->next_crypto->x);
@ -120,7 +156,11 @@ void dh_generate_x(SSH_SESSION *session){
/* used by server */
void dh_generate_y(SSH_SESSION *session){
session->next_crypto->y=bignum_new();
#ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->y,128);
#elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->y,128,0,-1);
#endif
/* not harder than this */
#ifdef DEBUG_CRYPTO
ssh_print_bignum("y",session->next_crypto->y);
@ -128,31 +168,46 @@ void dh_generate_y(SSH_SESSION *session){
}
/* used by server */
void dh_generate_e(SSH_SESSION *session){
#ifdef HAVE_LIBCRYPTO
bignum_CTX ctx=bignum_ctx_new();
#endif
session->next_crypto->e=bignum_new();
#ifdef HAVE_LIBGCRYPT
bignum_mod_exp(session->next_crypto->e,g,session->next_crypto->x,p);
#elif defined HAVE_LIBCRYPTO
bignum_mod_exp(session->next_crypto->e,g,session->next_crypto->x,p,ctx);
#endif
#ifdef DEBUG_CRYPTO
ssh_print_bignum("e",session->next_crypto->e);
#endif
#ifdef HAVE_LIBCRYPTO
bignum_ctx_free(ctx);
#endif
}
void dh_generate_f(SSH_SESSION *session){
#ifdef HAVE_LIBCRYPTO
bignum_CTX ctx=bignum_ctx_new();
#endif
session->next_crypto->f=bignum_new();
#ifdef HAVE_LIBGCRYPT
bignum_mod_exp(session->next_crypto->f,g,session->next_crypto->y,p);
#elif defined HAVE_LIBCRYPTO
bignum_mod_exp(session->next_crypto->f,g,session->next_crypto->y,p,ctx);
#endif
#ifdef DEBUG_CRYPTO
ssh_print_bignum("f",session->next_crypto->f);
#endif
#ifdef HAVE_LIBCRYPTO
bignum_ctx_free(ctx);
#endif
}
STRING *make_bignum_string(bignum num){
STRING *ptr;
int pad=0;
int len=bignum_num_bytes(num);
int bits=bignum_num_bits(num);
int finallen;
unsigned int len=bignum_num_bytes(num);
unsigned int bits=bignum_num_bits(num);
/* remember if the fist bit is set, it is considered as a negative number. so 0's must be appended */
if(!(bits%8) && bignum_is_bit_set(num,bits-1))
pad++;
@ -161,14 +216,24 @@ STRING *make_bignum_string(bignum num){
ptr->size=htonl(len+pad);
if(pad)
ptr->string[0]=0;
finallen=bignum_bn2bin(num,ptr->string+pad);
#ifdef HAVE_LIBGCRYPT
bignum_bn2bin(num,len,ptr->string+pad);
#elif HAVE_LIBCRYPTO
bignum_bn2bin(num,ptr->string+pad);
#endif
return ptr;
}
bignum make_string_bn(STRING *string){
int len=ntohl(string->size);
bignum bn;
unsigned int len=string_len(string);
ssh_say(3,"Importing a %d bits,%d bytes object ...\n",len*8,len);
return bignum_bin2bn(string->string,len,NULL);
#ifdef HAVE_LIBGCRYPT
bignum_bin2bn(string->string,len,&bn);
#elif defined HAVE_LIBCRYPTO
bn=bignum_bin2bn(string->string,len,NULL);
#endif
return bn;
}
STRING *dh_get_e(SSH_SESSION *session){
@ -200,21 +265,33 @@ void dh_import_e(SSH_SESSION *session, STRING *e_string){
}
void dh_build_k(SSH_SESSION *session){
#ifdef HAVE_LIBCRYPTO
bignum_CTX ctx=bignum_ctx_new();
#endif
session->next_crypto->k=bignum_new();
/* the server and clients don't use the same numbers */
#ifdef HAVE_LIBGCRYPT
if(session->client){
bignum_mod_exp(session->next_crypto->k,session->next_crypto->f,session->next_crypto->x,p);
} else {
bignum_mod_exp(session->next_crypto->k,session->next_crypto->e,session->next_crypto->y,p);
}
#elif defined HAVE_LIBCRYPTO
if(session->client){
bignum_mod_exp(session->next_crypto->k,session->next_crypto->f,session->next_crypto->x,p,ctx);
} else {
bignum_mod_exp(session->next_crypto->k,session->next_crypto->e,session->next_crypto->y,p,ctx);
}
#endif
#ifdef DEBUG_CRYPTO
ssh_print_bignum("shared secret key",session->next_crypto->k);
#endif
#ifdef HAVE_LIBCRYPTO
bignum_ctx_free(ctx);
#endif
}
/*
static void sha_add(STRING *str,SHACTX *ctx){
static void sha_add(STRING *str,SHACTX ctx){
sha1_update(ctx,str,string_len(str)+4);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("partial hashed sessionid",str,string_len(str)+4);
@ -222,7 +299,7 @@ static void sha_add(STRING *str,SHACTX *ctx){
}
*/
void make_sessionid(SSH_SESSION *session){
SHACTX *ctx;
SHACTX ctx;
STRING *num,*str;
BUFFER *server_hash, *client_hash;
BUFFER *buf=buffer_new();
@ -294,7 +371,7 @@ void make_sessionid(SSH_SESSION *session){
buffer_free(buf);
#ifdef DEBUG_CRYPTO
printf("Session hash : ");
ssh_print_hexa("session id",session->next_crypto->session_id,SHA_DIGEST_LENGTH);
ssh_print_hexa("session id",session->next_crypto->session_id,SHA_DIGEST_LEN);
#endif
}
@ -314,18 +391,18 @@ void hashbufin_add_cookie(SSH_SESSION *session,unsigned char *cookie){
buffer_add_data(session->in_hashbuf,cookie,16);
}
static void generate_one_key(STRING *k,char session_id[SHA_DIGEST_LENGTH],char output[SHA_DIGEST_LENGTH],char letter){
SHACTX *ctx=sha1_init();
static void generate_one_key(STRING *k,unsigned char session_id[SHA_DIGEST_LEN],unsigned char output[SHA_DIGEST_LEN],char letter){
SHACTX ctx=sha1_init();
sha1_update(ctx,k,string_len(k)+4);
sha1_update(ctx,session_id,SHA_DIGEST_LENGTH);
sha1_update(ctx,session_id,SHA_DIGEST_LEN);
sha1_update(ctx,&letter,1);
sha1_update(ctx,session_id,SHA_DIGEST_LENGTH);
sha1_update(ctx,session_id,SHA_DIGEST_LEN);
sha1_final(output,ctx);
}
void generate_session_keys(SSH_SESSION *session){
STRING *k_string;
SHACTX *ctx;
SHACTX ctx;
k_string=make_bignum_string(session->next_crypto->k);
/* IV */
@ -345,19 +422,19 @@ void generate_session_keys(SSH_SESSION *session){
}
/* some ciphers need more than 20 bytes of input key */
/* XXX verify it's ok for server implementation */
if(session->next_crypto->out_cipher->keylen > SHA_DIGEST_LENGTH*8){
if(session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN*8){
ctx=sha1_init();
sha1_update(ctx,k_string,string_len(k_string)+4);
sha1_update(ctx,session->next_crypto->session_id,SHA_DIGEST_LENGTH);
sha1_update(ctx,session->next_crypto->encryptkey,SHA_DIGEST_LENGTH);
sha1_update(ctx,session->next_crypto->session_id,SHA_DIGEST_LEN);
sha1_update(ctx,session->next_crypto->encryptkey,SHA_DIGEST_LEN);
sha1_final(session->next_crypto->encryptkey+SHA_DIGEST_LEN,ctx);
}
if(session->next_crypto->in_cipher->keylen > SHA_DIGEST_LENGTH*8){
if(session->next_crypto->in_cipher->keysize > SHA_DIGEST_LEN*8){
ctx=sha1_init();
sha1_update(ctx,k_string,string_len(k_string)+4);
sha1_update(ctx,session->next_crypto->session_id,SHA_DIGEST_LENGTH);
sha1_update(ctx,session->next_crypto->decryptkey,SHA_DIGEST_LENGTH);
sha1_update(ctx,session->next_crypto->session_id,SHA_DIGEST_LEN);
sha1_update(ctx,session->next_crypto->decryptkey,SHA_DIGEST_LEN);
sha1_final(session->next_crypto->decryptkey+SHA_DIGEST_LEN,ctx);
}
if(session->client){
@ -369,19 +446,19 @@ void generate_session_keys(SSH_SESSION *session){
}
#ifdef DEBUG_CRYPTO
ssh_print_hexa("encrypt IV",session->next_crypto->encryptIV,SHA_DIGEST_LENGTH);
ssh_print_hexa("decrypt IV",session->next_crypto->decryptIV,SHA_DIGEST_LENGTH);
ssh_print_hexa("encrypt IV",session->next_crypto->encryptIV,SHA_DIGEST_LEN);
ssh_print_hexa("decrypt IV",session->next_crypto->decryptIV,SHA_DIGEST_LEN);
ssh_print_hexa("encryption key",session->next_crypto->encryptkey,16);
ssh_print_hexa("decryption key",session->next_crypto->decryptkey,16);
ssh_print_hexa("Encryption MAC",session->next_crypto->encryptMAC,SHA_DIGEST_LENGTH);
ssh_print_hexa("Encryption MAC",session->next_crypto->encryptMAC,SHA_DIGEST_LEN);
ssh_print_hexa("Decryption MAC",session->next_crypto->decryptMAC,20);
#endif
free(k_string);
}
int ssh_get_pubkey_hash(SSH_SESSION *session,char hash[MD5_DIGEST_LEN]){
int ssh_get_pubkey_hash(SSH_SESSION *session,unsigned char hash[MD5_DIGEST_LEN]){
STRING *pubkey=session->current_crypto->server_pubkey;
MD5CTX *ctx;
MD5CTX ctx;
int len=string_len(pubkey);
ctx=md5_init();
@ -390,7 +467,7 @@ int ssh_get_pubkey_hash(SSH_SESSION *session,char hash[MD5_DIGEST_LEN]){
return MD5_DIGEST_LEN;
}
int pubkey_get_hash(SSH_SESSION *session, char hash[MD5_DIGEST_LEN]){
int pubkey_get_hash(SSH_SESSION *session, unsigned char hash[MD5_DIGEST_LEN]){
return ssh_get_pubkey_hash(session,hash);
}
@ -424,33 +501,59 @@ static int match(char *group,char *object){
}
static int sig_verify(SSH_SESSION *session, PUBLIC_KEY *pubkey, SIGNATURE *signature,
char *digest){
unsigned char *digest){
#ifdef HAVE_LIBGCRYPT
gcry_error_t valid=0;
gcry_sexp_t gcryhash;
#elif defined HAVE_LIBCRYPTO
int valid=0;
char hash[SHA_DIGEST_LENGTH];
sha1(digest,SHA_DIGEST_LENGTH,hash);
#endif
unsigned char hash[SHA_DIGEST_LEN+1];
sha1(digest,SHA_DIGEST_LEN,hash+1);
hash[0]=0;
#ifdef DEBUG_CRYPTO
ssh_print_hexa("hash to be verified with dsa",hash,SHA_DIGEST_LENGTH);
ssh_print_hexa("hash to be verified with dsa",hash+1,SHA_DIGEST_LEN);
#endif
switch(pubkey->type){
case TYPE_DSS:
valid=DSA_do_verify(hash,SHA_DIGEST_LENGTH,signature->dsa_sign,
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN+1, hash);
valid=gcry_pk_verify(signature->dsa_sign,gcryhash,pubkey->dsa_pub);
gcry_sexp_release(gcryhash);
if(valid==0)
return 0;
if (gcry_err_code(valid)!=GPG_ERR_BAD_SIGNATURE){
ssh_set_error(NULL,SSH_FATAL,"DSA error : %s", gcry_strerror(valid));
#elif defined HAVE_LIBCRYPTO
valid=DSA_do_verify(hash+1,SHA_DIGEST_LEN,signature->dsa_sign,
pubkey->dsa_pub);
if(valid==1)
return 0;
if(valid==-1){
ssh_set_error(session,SSH_FATAL,"DSA error : %s",ERR_error_string(ERR_get_error(),NULL));
#endif
return -1;
}
ssh_set_error(session,SSH_FATAL,"Invalid DSA signature");
return -1;
case TYPE_RSA:
case TYPE_RSA1:
valid=RSA_verify(NID_sha1,hash,SHA_DIGEST_LENGTH,
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&gcryhash,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1);
valid=gcry_pk_verify(signature->rsa_sign,gcryhash,pubkey->rsa_pub);
gcry_sexp_release(gcryhash);
if(valid==0)
return 0;
if(gcry_err_code(valid)!=GPG_ERR_BAD_SIGNATURE){
ssh_set_error(NULL,SSH_FATAL,"RSA error : %s",gcry_strerror(valid));
#elif defined HAVE_LIBCRYPTO
valid=RSA_verify(NID_sha1,hash+1,SHA_DIGEST_LEN,
signature->rsa_sign->string,string_len(signature->rsa_sign),pubkey->rsa_pub);
if(valid==1)
return 0;
if(valid==-1){
ssh_set_error(session,SSH_FATAL,"RSA error : %s",ERR_error_string(ERR_get_error(),NULL));
#endif
return -1;
}
ssh_set_error(session,SSH_FATAL,"Invalid RSA signature");

Просмотреть файл

@ -29,6 +29,7 @@ MA 02111-1307, USA. */
#ifndef NO_GZIP
#include <zlib.h>
#include <string.h>
#include <stdlib.h>
#define BLOCKSIZE 4092
static z_stream *initcompress(SSH_SESSION *session,int level){

Просмотреть файл

@ -26,6 +26,11 @@ MA 02111-1307, USA. */
#include "libssh/ssh2.h"
#include "libssh/ssh1.h"
#ifdef HAVE_LIBGCRYPT
#define BLOWFISH "blowfish-cbc,"
#define AES "aes256-cbc,aes192-cbc,aes128-cbc,"
#define DES "3des-cbc"
#elif defined HAVE_LIBCRYPTO
#ifdef HAVE_OPENSSL_BLOWFISH_H
#define BLOWFISH "blowfish-cbc,"
#else
@ -36,13 +41,15 @@ MA 02111-1307, USA. */
#else
#define AES ""
#endif
#define DES "3des-cbc"
#endif
#ifdef HAVE_LIBZ
#define ZLIB "none,zlib"
#else
#define ZLIB "none"
#endif
char *default_methods[]={
"diffie-hellman-group1-sha1","ssh-dss,ssh-rsa",AES BLOWFISH DES,AES BLOWFISH
DES, "hmac-sha1","hmac-sha1","none","none","","",NULL };
@ -286,7 +293,7 @@ static STRING *make_rsa1_string(STRING *e, STRING *n){
static void build_session_id1(SSH_SESSION *session, STRING *servern,
STRING *hostn){
MD5CTX *md5=md5_init();
MD5CTX md5=md5_init();
#ifdef DEBUG_CRYPTO
ssh_print_hexa("host modulus",hostn->string,string_len(hostn));
ssh_print_hexa("server modulus",servern->string,string_len(servern));
@ -313,7 +320,7 @@ static int modulus_smaller(PUBLIC_KEY *k1, PUBLIC_KEY *k2){
#define ABS(A) ( (A)<0 ? -(A):(A) )
STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *svrkey,
PUBLIC_KEY *hostkey,int slen, int hlen ){
char buffer[32];
unsigned char buffer[32];
int i;
STRING *data1,*data2;
/* first, generate a session key */

Просмотреть файл

@ -28,12 +28,431 @@ MA 02111-1307, USA. */
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include "libssh/priv.h"
#ifdef HAVE_LIBCRYPTO
#include <openssl/pem.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include "libssh/priv.h"
#endif
#include <netinet/in.h>
#define MAXLINESIZE 80
#ifdef HAVE_LIBGCRYPT
#define MAX_KEY_SIZE 32
#define MAX_PASSPHRASE_SIZE 1024
#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
#define ASN1_INTEGER 2
#define ASN1_SEQUENCE 48
#define PKCS5_SALT_LEN 8
int load_iv(char *header, unsigned char *iv, int iv_len)
{
int i;
int j;
int k;
memset(iv, 0, iv_len);
for (i=0; i < iv_len; i++)
{
if ((header[2*i] >= '0') && (header[2*i] <= '9'))
j = header[2*i] - '0';
else if ((header[2*i] >= 'A') && (header[2*i] <= 'F'))
j = header[2*i] - 'A' + 10;
else if ((header[2*i] >= 'a') && (header[2*i] <= 'f'))
j = header[2*i] - 'a' + 10;
else
return 0;
if ((header[2*i+1] >= '0') && (header[2*i+1] <= '9'))
k = header[2*i+1] - '0';
else if ((header[2*i+1] >= 'A') && (header[2*i+1] <= 'F'))
k = header[2*i+1] - 'A' + 10;
else if ((header[2*i+1] >= 'a') && (header[2*i+1] <= 'f'))
k = header[2*i+1] - 'a' + 10;
else
return 0;
iv[i] = (j << 4) + k;
}
return 1;
}
u32 char_to_u32(unsigned char *data, u32 size)
{
u32 ret;
u32 i;
for (i=0,ret=0;i<size;ret=ret<<8,ret+=data[i++])
;
return ret;
}
u32 asn1_get_len(BUFFER *buffer)
{
u32 len;
unsigned char tmp[4];
if (!buffer_get_data(buffer,tmp,1))
return 0;
if (tmp[0] > 127)
{
len=tmp[0] & 127;
if (len>4)
return 0; /* Length doesn't fit in u32. Can this really happen? */
if (!buffer_get_data(buffer,tmp,len))
return 0;
len=char_to_u32(tmp,len);
}
else
len=char_to_u32(tmp,1);
return len;
}
STRING *asn1_get_int(BUFFER *buffer)
{
STRING *ret;
unsigned char type;
u32 size;
if (!buffer_get_data(buffer,&type,1) || type != ASN1_INTEGER)
return NULL;
size=asn1_get_len(buffer);
if (!size)
return NULL;
ret=string_new(size);
if (!buffer_get_data(buffer,ret->string,size))
return NULL;
return ret;
}
int asn1_check_sequence(BUFFER *buffer)
{
unsigned char tmp;
unsigned char *j;
int i;
u32 size;
if (!buffer_get_data(buffer,&tmp,1) || tmp != ASN1_SEQUENCE)
return 0;
size=asn1_get_len(buffer);
if (size != buffer_get_len(buffer) - buffer->pos)
for (i = buffer_get_len(buffer) - buffer->pos - size,
j = buffer_get(buffer) + size + buffer->pos; i; i--, j++)
{
if (*j != 1) /* padding is allowed */
return 0; /* but nothing else */
}
return 1;
}
int read_line(char *data, unsigned int len, FILE *fp)
{
char tmp;
int i;
for (i=0; fread(&tmp, 1, 1, fp) && tmp!='\n' && i<len; data[i++]=tmp)
;
if (tmp=='\n')
return i;
if (i>=len)
return -1;
return 0;
}
int passphrase_to_key(char *data, unsigned int datalen, unsigned char *salt, unsigned char *key,unsigned int keylen)
{
MD5CTX md;
unsigned char digest[MD5_DIGEST_LEN];
unsigned int i;
unsigned int j;
unsigned int md_not_empty;
for (j=0,md_not_empty=0;j<keylen;)
{
md = md5_init();
if (!md)
return 0;
if (md_not_empty)
md5_update(md,digest,MD5_DIGEST_LEN);
else
md_not_empty=1;
md5_update(md,data,datalen);
if (salt)
md5_update(md, salt, PKCS5_SALT_LEN);
md5_final(digest,md);
for (i = 0; j < keylen && i < MD5_DIGEST_LEN; j++, i++)
if (key)
key[j] = digest[i];
}
return 1;
}
int privatekey_decrypt(int algo, int mode, unsigned int key_len,
unsigned char *iv, unsigned int iv_len,
BUFFER *data, int cb(char *,int , int , char *),
char *desc)
{
gcry_cipher_hd_t cipher;
unsigned int passphrase_len;
char passphrase[MAX_PASSPHRASE_SIZE];
unsigned char key[MAX_KEY_SIZE];
unsigned char *tmp;
gcry_error_t err;
if (!algo)
return 1;
passphrase_len=cb(passphrase, MAX_PASSPHRASE_SIZE, 0, desc);
if (passphrase_len <= 0)
return 0;
passphrase_to_key(passphrase, passphrase_len, iv, key, key_len);
if (gcry_cipher_open(&cipher, algo, mode, GCRY_CIPHER_SECURE)
|| gcry_cipher_setkey(cipher, key, key_len)
|| gcry_cipher_setiv(cipher, iv, iv_len)
|| !(tmp = malloc(buffer_get_len(data) * sizeof (char)))
|| (err = gcry_cipher_decrypt(cipher, tmp, buffer_get_len(data),
buffer_get(data), buffer_get_len(data))))
{
gcry_cipher_close(cipher);
return 0;
}
memcpy(buffer_get(data), tmp, buffer_get_len(data));
gcry_cipher_close(cipher);
return 1;
}
int privatekey_dek_header(char *header, unsigned int header_len, int *algo, int *mode, unsigned int *key_len, unsigned char **iv, unsigned int *iv_len)
{
unsigned int iv_pos;
if (header_len > 13 && !strncmp("DES-EDE3-CBC", header, 12))
{
*algo = GCRY_CIPHER_3DES;
iv_pos = 13;
*mode = GCRY_CIPHER_MODE_CBC;
*key_len = 24;
*iv_len = 8;
}
else if (header_len > 8 && !strncmp("DES-CBC", header, 7))
{
*algo = GCRY_CIPHER_DES;
iv_pos = 8;
*mode = GCRY_CIPHER_MODE_CBC;
*key_len = 8;
*iv_len = 8;
}
else if (header_len > 12 && !strncmp("AES-128-CBC", header, 11))
{
*algo = GCRY_CIPHER_AES128;
iv_pos = 12;
*mode = GCRY_CIPHER_MODE_CBC;
*key_len = 16;
*iv_len = 16;
}
else if (header_len > 12 && !strncmp("AES-192-CBC", header, 11))
{
*algo = GCRY_CIPHER_AES192;
iv_pos = 12;
*mode = GCRY_CIPHER_MODE_CBC;
*key_len = 24;
*iv_len = 16;
}
else if (header_len > 12 && !strncmp("AES-256-CBC", header, 11))
{
*algo = GCRY_CIPHER_AES256;
iv_pos = 12;
*mode = GCRY_CIPHER_MODE_CBC;
*key_len = 32;
*iv_len = 16;
}
else
return 0;
*iv = malloc(*iv_len);
load_iv(header + iv_pos, *iv, *iv_len);
return 1;
}
BUFFER *privatekey_file_to_buffer(FILE *fp, int type, int cb(char *, int , int , char *), char *desc)
{
char buf[MAXLINESIZE];
char *header_begin;
unsigned int header_begin_size;
char *header_end;
unsigned int header_end_size;
BUFFER *buffer=buffer_new();
BUFFER *ret;
int len;
int algo = 0;
int mode = 0;
unsigned int key_len = 0;
unsigned char *iv = NULL;
unsigned int iv_len = 0;
switch(type)
{
case TYPE_DSS:
header_begin=DSA_HEADER_BEGIN;
header_end=DSA_HEADER_END;
break;
case TYPE_RSA:
header_begin=RSA_HEADER_BEGIN;
header_end=RSA_HEADER_END;
break;
default:
return NULL;
}
header_begin_size=strlen(header_begin);
header_end_size=strlen(header_end);
while (read_line(buf,MAXLINESIZE,fp) && strncmp(buf,header_begin,header_begin_size))
;
len = read_line(buf, MAXLINESIZE, fp);
if (len > 11 && !strncmp("Proc-Type: 4,ENCRYPTED", buf, 11))
{
len = read_line(buf, MAXLINESIZE, fp);
if (len > 10 && !strncmp("DEK-Info: ", buf, 10))
{
if (!privatekey_dek_header(buf + 10, len - 10, &algo, &mode, &key_len,
&iv, &iv_len)
|| read_line(buf, MAXLINESIZE, fp))
{
buffer_free(buffer);
free(iv);
return NULL;
}
}
else
{
buffer_free(buffer);
free(iv);
return NULL;
}
}
else
buffer_add_data(buffer,buf,len);
while ((len = read_line(buf,MAXLINESIZE,fp))
&& strncmp(buf,header_end,header_end_size))
{
if (len == -1)
{
buffer_free(buffer);
free(iv);
return NULL;
}
buffer_add_data(buffer,buf,len);
}
if (strncmp(buf,header_end,header_end_size))
{
buffer_free(buffer);
free(iv);
return NULL;
}
buffer_add_data(buffer,"\0",1);
ret=base64_to_bin(buffer_get(buffer));
buffer_free(buffer);
if (algo)
{
if (!privatekey_decrypt(algo, mode, key_len, iv, iv_len, ret, cb, desc))
{
free(iv);
return NULL;
}
}
free(iv);
return ret;
}
int read_rsa_privatekey(FILE *fp, gcry_sexp_t *r,
int cb(char *, int , int , char *), char *desc)
{
STRING *n;
STRING *e;
STRING *d;
STRING *p;
STRING *q;
STRING *unused1;
STRING *unused2;
STRING *u;
STRING *v;
BUFFER *buffer;
if (!(buffer=privatekey_file_to_buffer(fp, TYPE_RSA, cb, desc)))
return 0;
if (!asn1_check_sequence(buffer))
{
buffer_free(buffer);
return 0;
}
v=asn1_get_int(buffer);
if (ntohl(v->size)!=1 || v->string[0]!=0)
{
buffer_free(buffer);
return 0;
}
n=asn1_get_int(buffer);
e=asn1_get_int(buffer);
d=asn1_get_int(buffer);
q=asn1_get_int(buffer);
p=asn1_get_int(buffer);
unused1=asn1_get_int(buffer);
unused2=asn1_get_int(buffer);
u=asn1_get_int(buffer);
buffer_free(buffer);
if (!n || !e || !d || !p || !q || !unused1 || !unused2 || !u)
return 0;
gcry_sexp_build(r,NULL,"(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",ntohl(n->size),n->string,ntohl(e->size),e->string,ntohl(d->size),d->string,ntohl(p->size),p->string,ntohl(q->size),q->string,ntohl(u->size),u->string);
free(n);
free(e);
free(d);
free(p);
free(q);
free(unused1);
free(unused2);
free(u);
free(v);
return 1;
}
int read_dsa_privatekey(FILE *fp, gcry_sexp_t *r, int cb(char *, int , int , char *), char *desc)
{
STRING *p;
STRING *q;
STRING *g;
STRING *y;
STRING *x;
STRING *v;
BUFFER *buffer;
if (!(buffer=privatekey_file_to_buffer(fp, TYPE_DSS, cb, desc)))
return 0;
if (!asn1_check_sequence(buffer))
{
buffer_free(buffer);
return 0;
}
v=asn1_get_int(buffer);
if (ntohl(v->size)!=1 || v->string[0]!=0)
{
buffer_free(buffer);
return 0;
}
p=asn1_get_int(buffer);
q=asn1_get_int(buffer);
g=asn1_get_int(buffer);
y=asn1_get_int(buffer);
x=asn1_get_int(buffer);
buffer_free(buffer);
if (!p || !q || !g || !y || !x)
return 0;
gcry_sexp_build(r,NULL,"(private-key(dsa(p %b)(q %b)(g %b)(y %b)(x %b)))",ntohl(p->size),p->string,ntohl(q->size),q->string,ntohl(g->size),g->string,ntohl(y->size),y->string,ntohl(x->size),x->string);
free(p);
free(q);
free(g);
free(y);
free(x);
free(v);
return 1;
}
#endif /* GCRYPT */
static int default_get_password(char *buf, int size,int rwflag, char *descr){
char *pass;
@ -41,7 +460,7 @@ static int default_get_password(char *buf, int size,int rwflag, char *descr){
int len;
snprintf(buffer,256,"Please enter passphrase for %s",descr);
pass=getpass(buffer);
snprintf(buf,size,"%s",buffer);
snprintf(buf,size,"%s",pass);
len=strlen(buf);
memset(pass,0,strlen(pass));
return len;
@ -57,8 +476,14 @@ static int get_password_specified(char *buf,int size, int rwflag, char *password
PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,char *passphrase){
FILE *file=fopen(filename,"r");
PRIVATE_KEY *privkey;
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa=NULL;
gcry_sexp_t rsa=NULL;
int valid;
#elif defined HAVE_LIBCRYPTO
DSA *dsa=NULL;
RSA *rsa=NULL;
#endif
if(!file){
ssh_set_error(session,SSH_REQUEST_DENIED,"Error opening %s : %s",filename,strerror(errno));
return NULL;
@ -66,6 +491,17 @@ PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,
if(type==TYPE_DSS){
if(!passphrase){
if(session && session->options->passphrase_function)
#ifdef HAVE_LIBGCRYPT
valid = read_dsa_privatekey(file,&dsa, session->options->passphrase_function,"DSA private key");
else
valid = read_dsa_privatekey(file,&dsa,(void *)default_get_password, "DSA private key");
}
else
valid = read_dsa_privatekey(file,&dsa,(void *)get_password_specified,passphrase);
fclose(file);
if(!valid){
ssh_set_error(session,SSH_FATAL,"parsing private key %s",filename);
#elif defined HAVE_LIBCRYPTO
dsa=PEM_read_DSAPrivateKey(file,NULL, session->options->passphrase_function,"DSA private key");
else
dsa=PEM_read_DSAPrivateKey(file,NULL,(void *)default_get_password, "DSA private key");
@ -76,12 +512,24 @@ PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,
if(!dsa){
ssh_set_error(session,SSH_FATAL,"parsing private key %s"
": %s",filename,ERR_error_string(ERR_get_error(),NULL));
#endif
return NULL;
}
}
else if (type==TYPE_RSA){
if(!passphrase){
if(session && session->options->passphrase_function)
#ifdef HAVE_LIBGCRYPT
valid = read_rsa_privatekey(file,&rsa, session->options->passphrase_function,"RSA private key");
else
valid = read_rsa_privatekey(file,&rsa,(void *)default_get_password, "RSA private key");
}
else
valid = read_rsa_privatekey(file,&rsa,(void *)get_password_specified,passphrase);
fclose(file);
if(!valid){
ssh_set_error(session,SSH_FATAL,"parsing private key %s",filename);
#elif defined HAVE_LIBCRYPTO
rsa=PEM_read_RSAPrivateKey(file,NULL, session->options->passphrase_function,"RSA private key");
else
rsa=PEM_read_RSAPrivateKey(file,NULL,(void *)default_get_password, "RSA private key");
@ -92,6 +540,7 @@ PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,
if(!rsa){
ssh_set_error(session,SSH_FATAL,"parsing private key %s"
": %s",filename,ERR_error_string(ERR_get_error(),NULL));
#endif
return NULL;
}
} else {
@ -110,27 +559,49 @@ PRIVATE_KEY *privatekey_from_file(SSH_SESSION *session,char *filename,int type,
PRIVATE_KEY *_privatekey_from_file(void *session,char *filename,int type){
FILE *file=fopen(filename,"r");
PRIVATE_KEY *privkey;
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa=NULL;
gcry_sexp_t rsa=NULL;
int valid;
#elif defined HAVE_LIBCRYPTO
DSA *dsa=NULL;
RSA *rsa=NULL;
#endif
if(!file){
ssh_set_error(session,SSH_REQUEST_DENIED,"Error opening %s : %s",filename,strerror(errno));
return NULL;
}
if(type==TYPE_DSS){
#ifdef HAVE_LIBGCRYPT
valid=read_dsa_privatekey(file,&dsa,NULL,NULL);
fclose(file);
if(!valid){
ssh_set_error(session,SSH_FATAL,"parsing private key %s"
,filename);
#elif defined HAVE_LIBCRYPTO
dsa=PEM_read_DSAPrivateKey(file,NULL,NULL,NULL);
fclose(file);
if(!dsa){
ssh_set_error(session,SSH_FATAL,"parsing private key %s"
": %s",filename,ERR_error_string(ERR_get_error(),NULL));
#endif
return NULL;
}
}
else if (type==TYPE_RSA){
#ifdef HAVE_LIBGCRYPT
valid=read_rsa_privatekey(file,&rsa,NULL,NULL);
fclose(file);
if(!valid){
ssh_set_error(session,SSH_FATAL,"parsing private key %s"
,filename);
#elif defined HAVE_LIBCRYPTO
rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL);
fclose(file);
if(!rsa){
ssh_set_error(session,SSH_FATAL,"parsing private key %s"
": %s",filename,ERR_error_string(ERR_get_error(),NULL));
#endif
return NULL;
}
} else {
@ -145,10 +616,17 @@ PRIVATE_KEY *_privatekey_from_file(void *session,char *filename,int type){
}
void private_key_free(PRIVATE_KEY *prv){
#ifdef HAVE_LIBGCRYPT
if(prv->dsa_priv)
gcry_sexp_release(prv->dsa_priv);
if(prv->rsa_priv)
gcry_sexp_release(prv->rsa_priv);
#elif defined HAVE_LIBCRYPTO
if(prv->dsa_priv)
DSA_free(prv->dsa_priv);
if(prv->rsa_priv)
RSA_free(prv->rsa_priv);
#endif
memset(prv,0,sizeof(PRIVATE_KEY));
free(prv);
}
@ -359,7 +837,7 @@ int ssh_is_server_known(SSH_SESSION *session){
}
int ssh_write_knownhost(SSH_SESSION *session){
char *pubkey_64;
unsigned char *pubkey_64;
STRING *pubkey=session->current_crypto->server_pubkey;
char buffer[4096];
FILE *file;

Просмотреть файл

@ -20,9 +20,13 @@ 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 <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#ifdef HAVE_LIBCRYPTO
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#endif
#include "libssh/priv.h"
@ -63,11 +67,15 @@ PUBLIC_KEY *publickey_make_dss(BUFFER *buffer){
free(key);
return NULL;
}
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&key->dsa_pub,NULL,"(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",string_len(p),p->string,string_len(q),q->string,string_len(g),g->string,string_len(pubkey),pubkey->string);
#elif defined HAVE_LIBCRYPTO
key->dsa_pub=DSA_new();
key->dsa_pub->p=make_string_bn(p);
key->dsa_pub->q=make_string_bn(q);
key->dsa_pub->g=make_string_bn(g);
key->dsa_pub->pub_key=make_string_bn(pubkey);
#endif
free(p);
free(q);
free(g);
@ -95,12 +103,16 @@ PUBLIC_KEY *publickey_make_rsa(BUFFER *buffer, char *type){
free(key);
return NULL;
}
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&key->rsa_pub,NULL,"(public-key(rsa(n %b)(e %b)))",string_len(n),n->string,string_len(e),e->string);
#elif HAVE_LIBCRYPTO
key->rsa_pub=RSA_new();
key->rsa_pub->e=make_string_bn(e);
key->rsa_pub->n=make_string_bn(n);
#endif
#ifdef DEBUG_CRYPTO
ssh_print_bignum("e",key->rsa_pub->e);
ssh_print_bignum("n",key->rsa_pub->n);
ssh_print_hexa("e",e->string,string_len(e));
ssh_print_hexa("n",n->string,string_len(n));
#endif
free(e);
free(n);
@ -112,11 +124,19 @@ void publickey_free(PUBLIC_KEY *key){
return;
switch(key->type){
case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
gcry_sexp_release(key->dsa_pub);
#elif HAVE_LIBCRYPTO
DSA_free(key->dsa_pub);
#endif
break;
case TYPE_RSA:
case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
gcry_sexp_release(key->rsa_pub);
#elif defined HAVE_LIBCRYPTO
RSA_free(key->rsa_pub);
#endif
break;
default:
break;
@ -158,32 +178,112 @@ PUBLIC_KEY *publickey_from_string(STRING *pubkey_s){
PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv){
PUBLIC_KEY *key=malloc(sizeof(PUBLIC_KEY));
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t sexp;
const char *tmp;
size_t size;
STRING *p,*q,*g,*y,*e,*n;
#endif
key->type=prv->type;
switch(key->type){
case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
sexp=gcry_sexp_find_token(prv->dsa_priv,"p",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
p=string_new(size);
string_fill(p,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(prv->dsa_priv,"q",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
q=string_new(size);
string_fill(q,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(prv->dsa_priv,"g",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
g=string_new(size);
string_fill(g,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(prv->dsa_priv,"y",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
y=string_new(size);
string_fill(y,(char *)tmp,size);
gcry_sexp_release(sexp);
gcry_sexp_build(&key->dsa_pub,NULL,"(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",string_len(p),p->string,string_len(q),q->string,string_len(g),g->string,string_len(y),y->string);
free(p);
free(q);
free(g);
free(y);
#elif defined HAVE_LIBCRYPTO
key->dsa_pub=DSA_new();
key->dsa_pub->p=BN_dup(prv->dsa_priv->p);
key->dsa_pub->q=BN_dup(prv->dsa_priv->q);
key->dsa_pub->pub_key=BN_dup(prv->dsa_priv->pub_key);
key->dsa_pub->g=BN_dup(prv->dsa_priv->g);
#endif
break;
case TYPE_RSA:
case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
sexp=gcry_sexp_find_token(prv->rsa_priv,"n",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
n=string_new(size);
string_fill(n,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(prv->rsa_priv,"e",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
e=string_new(size);
string_fill(e,(char *)tmp,size);
gcry_sexp_release(sexp);
gcry_sexp_build(&key->rsa_pub,NULL,"(public-key(rsa(n %b)(e %b)))",string_len(n),n->string,string_len(e),e->string);
free(e);
free(n);
#elif defined HAVE_LIBCRYPTO
key->rsa_pub=RSA_new();
key->rsa_pub->e=BN_dup(prv->rsa_priv->e);
key->rsa_pub->n=BN_dup(prv->rsa_priv->n);
#endif
break;
}
key->type_c=ssh_type_to_char(prv->type);
return key;
}
#ifdef HAVE_LIBGCRYPT
static void dsa_public_to_string(gcry_sexp_t key, BUFFER *buffer){
#elif defined HAVE_LIBCRYPTO
static void dsa_public_to_string(DSA *key, BUFFER *buffer){
#endif
STRING *p,*q,*g,*n;
#ifdef HAVE_LIBGCRYPT
const char *tmp;
size_t size;
gcry_sexp_t sexp;
sexp=gcry_sexp_find_token(key,"p",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
p=string_new(size);
string_fill(p,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(key,"q",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
q=string_new(size);
string_fill(q,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(key,"g",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
g=string_new(size);
string_fill(g,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(key,"y",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
n=string_new(size);
string_fill(n,(char *)tmp,size);
gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
p=make_bignum_string(key->p);
q=make_bignum_string(key->q);
g=make_bignum_string(key->g);
n=make_bignum_string(key->pub_key);
#endif
buffer_add_ssh_string(buffer,p);
buffer_add_ssh_string(buffer,q);
buffer_add_ssh_string(buffer,g);
@ -194,10 +294,30 @@ static void dsa_public_to_string(DSA *key, BUFFER *buffer){
free(n);
}
#ifdef HAVE_LIBGCRYPT
static void rsa_public_to_string(gcry_sexp_t key, BUFFER *buffer){
#elif defined HAVE_LIBCRYPTO
static void rsa_public_to_string(RSA *key, BUFFER *buffer){
#endif
STRING *e, *n;
#ifdef HAVE_LIBGCRYPT
const char *tmp;
size_t size;
gcry_sexp_t sexp;
sexp=gcry_sexp_find_token(key,"n",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
n=string_new(size);
string_fill(n,(char *)tmp,size);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(key,"e",0);
tmp=gcry_sexp_nth_data(sexp,1,&size);
e=string_new(size);
string_fill(e,(char *)tmp,size);
gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
e=make_bignum_string(key->e);
n=make_bignum_string(key->n);
#endif
buffer_add_ssh_string(buffer,e);
buffer_add_ssh_string(buffer,n);
free(e);
@ -231,7 +351,14 @@ STRING *publickey_to_string(PUBLIC_KEY *key){
STRING *signature_to_string(SIGNATURE *sign){
STRING *str;
STRING *rs,*r,*s;
STRING *rs;
#ifdef HAVE_LIBGCRYPT
const char *r,*s;
gcry_sexp_t sexp;
size_t size;
#elif defined HAVE_LIBCRYPTO
STRING *r,*s;
#endif
unsigned char buffer[40];
BUFFER *tmpbuf=buffer_new();
STRING *tmp;
@ -240,21 +367,58 @@ STRING *signature_to_string(SIGNATURE *sign){
free(tmp);
switch(sign->type){
case TYPE_DSS:
memset(buffer,0,40);
#ifdef HAVE_LIBGCRYPT
sexp=gcry_sexp_find_token(sign->dsa_sign,"r",0);
r=gcry_sexp_nth_data(sexp,1,&size);
if (*r == 0) /* libgcrypt put 0 when first bit is set */
{
size--;
r++;
}
memcpy(buffer,r + size - 20,20);
gcry_sexp_release(sexp);
sexp=gcry_sexp_find_token(sign->dsa_sign,"s",0);
s=gcry_sexp_nth_data(sexp,1,&size);
if (*s == 0)
{
size--;
s++;
}
memcpy(buffer+ 20, s + size - 20, 20);
gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
r=make_bignum_string(sign->dsa_sign->r);
s=make_bignum_string(sign->dsa_sign->s);
rs=string_new(40);
memset(buffer,0,40);
memcpy(buffer,r->string+string_len(r)-20,20);
memcpy(buffer+ 20, s->string + string_len(s) - 20, 20);
string_fill(rs,buffer,40);
free(r);
free(s);
#endif
rs=string_new(40);
string_fill(rs,buffer,40);
buffer_add_ssh_string(tmpbuf,rs);
free(rs);
break;
case TYPE_RSA:
case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
sexp=gcry_sexp_find_token(sign->rsa_sign,"s",0);
s=gcry_sexp_nth_data(sexp,1,&size);
if (*s == 0)
{
size--;
s++;
}
rs=string_new(size);
string_fill(rs,(char *)s,size);
buffer_add_ssh_string(tmpbuf,rs);
gcry_sexp_release(sexp);
free(rs);
#elif defined HAVE_LIBCRYPTO
buffer_add_ssh_string(tmpbuf,sign->rsa_sign);
#endif
break;
}
str=string_new(buffer_get_len(tmpbuf));
@ -265,11 +429,16 @@ STRING *signature_to_string(SIGNATURE *sign){
/* TODO : split this function in two so it becomes smaller */
SIGNATURE *signature_from_string(STRING *signature,PUBLIC_KEY *pubkey,int needed_type){
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t sig;
#elif defined HAVE_LIBCRYPTO
DSA_SIG *sig;
STRING *r,*s;
#endif
SIGNATURE *sign=malloc(sizeof(SIGNATURE));
BUFFER *tmpbuf=buffer_new();
STRING *rs;
STRING *r,*s,*type_s,*e;
STRING *type_s,*e;
int len,rsalen;
char *type;
buffer_add_data(tmpbuf,signature->string,string_len(signature));
@ -314,21 +483,25 @@ SIGNATURE *signature_from_string(STRING *signature,PUBLIC_KEY *pubkey,int needed
free(rs);
return NULL;
}
/* we make use of strings because we have all-made functions to convert them to bignums */
/* we make use of strings (because we have all-made functions to convert them to bignums (ou pas ;)*/
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&sig,NULL,"(sig-val(dsa(r %b)(s %b)))",20,rs->string,20,rs->string+20);
#elif defined HAVE_LIBCRYPTO
r=string_new(20);
s=string_new(20);
string_fill(r,rs->string,20);
string_fill(s,rs->string+20,20);
free(rs);
sig=DSA_SIG_new();
sig->r=make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
sig->s=make_string_bn(s);
#ifdef DEBUG_CRYPTO
ssh_print_bignum("r",sig->r);
ssh_print_bignum("s",sig->s);
#endif
free(r);
free(s);
#endif
#ifdef DEBUG_CRYPTO
ssh_print_hexa("r",rs->string,20);
ssh_print_hexa("s",rs->string+20,20);
#endif
free(rs);
sign->type=TYPE_DSS;
sign->dsa_sign=sig;
return sign;
@ -336,11 +509,14 @@ SIGNATURE *signature_from_string(STRING *signature,PUBLIC_KEY *pubkey,int needed
e=buffer_get_ssh_string(tmpbuf);
buffer_free(tmpbuf);
if(!e){
free(e);
return NULL;
return NULL;
}
len=string_len(e);
#ifdef HAVE_LIBGCRYPT
rsalen=(gcry_pk_get_nbits(pubkey->rsa_pub)+7)/8;
#elif defined HAVE_LIBCRYPTO
rsalen=RSA_size(pubkey->rsa_pub);
#endif
if(len>rsalen){
free(e);
free(sign);
@ -350,10 +526,18 @@ SIGNATURE *signature_from_string(STRING *signature,PUBLIC_KEY *pubkey,int needed
if(len<rsalen)
ssh_say(0,"Len %d < %d\n",len,rsalen);
sign->type=TYPE_RSA;
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&sig,NULL,"(sig-val(rsa(s %b)))",string_len(e),e->string);
sign->rsa_sign=sig;
#elif defined HAVE_LIBCRYPTO
sign->rsa_sign=e;
#endif
#ifdef DEBUG_CRYPTO
ssh_say(0,"Len : %d\n",len);
ssh_print_hexa("rsa signature",e->string,len);
#endif
#ifdef HAVE_LIBGCRYPT
free(e);
#endif
return sign;
default:
@ -366,11 +550,19 @@ void signature_free(SIGNATURE *sign){
return;
switch(sign->type){
case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
gcry_sexp_release(sign->dsa_sign);
#elif defined HAVE_LIBCRYPTO
DSA_SIG_free(sign->dsa_sign);
#endif
break;
case TYPE_RSA:
case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
gcry_sexp_release(sign->rsa_sign);
#elif defined HAVE_LIBCRYPTO
free(sign->rsa_sign);
#endif
break;
default:
ssh_say(1,"freeing a signature with no type !\n");
@ -378,6 +570,7 @@ void signature_free(SIGNATURE *sign){
free(sign);
}
#ifdef HAVE_LIBCRYPTO
/* maybe the missing function from libcrypto */
/* i think now, maybe it's a bad idea to name it has it should have be named in libcrypto */
static STRING *RSA_do_sign(void *payload,int len,RSA *privkey){
@ -395,42 +588,64 @@ static STRING *RSA_do_sign(void *payload,int len,RSA *privkey){
free(buffer);
return sign;
}
#endif
/* this function signs the session id (known as H) as a string then the content of sigbuf */
STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf, PRIVATE_KEY *privatekey){
SHACTX *ctx;
SHACTX ctx;
STRING *session_str=string_new(SHA_DIGEST_LEN);
char hash[SHA_DIGEST_LEN];
unsigned char hash[SHA_DIGEST_LEN+1];
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t gcryhash;
#endif
SIGNATURE *sign;
STRING *signature;
CRYPTO *crypto=session->current_crypto?session->current_crypto:session->next_crypto;
string_fill(session_str,crypto->session_id,SHA_DIGEST_LENGTH);
string_fill(session_str,crypto->session_id,SHA_DIGEST_LEN);
ctx=sha1_init();
sha1_update(ctx,session_str,string_len(session_str)+4);
sha1_update(ctx,buffer_get(sigbuf),buffer_get_len(sigbuf));
sha1_final(hash,ctx);
sha1_final(hash+1,ctx);
hash[0]=0;
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Hash being signed with dsa",hash,SHA_DIGEST_LENGTH);
ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN);
#endif
free(session_str);
sign=malloc(sizeof(SIGNATURE));
switch(privatekey->type){
case TYPE_DSS:
sign->dsa_sign=DSA_do_sign(hash,SHA_DIGEST_LENGTH,privatekey->dsa_priv);
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&gcryhash,NULL,"%b",SHA_DIGEST_LEN+1,hash);
gcry_pk_sign(&sign->dsa_sign,gcryhash,privatekey->dsa_priv);
#elif defined HAVE_LIBCRYPTO
sign->dsa_sign=DSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->dsa_priv);
#ifdef DEBUG_CRYPTO
ssh_print_bignum("r",sign->dsa_sign->r);
ssh_print_bignum("s",sign->dsa_sign->s);
#endif
#endif
sign->rsa_sign=NULL;
break;
case TYPE_RSA:
sign->rsa_sign=RSA_do_sign(hash,SHA_DIGEST_LENGTH,privatekey->rsa_priv);
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&gcryhash,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1);
gcry_pk_sign(&sign->rsa_sign,gcryhash,privatekey->rsa_priv);
#elif defined HAVE_LIBCRYPTO
sign->rsa_sign=RSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->rsa_priv);
#endif
sign->dsa_sign=NULL;
break;
}
#ifdef HAVE_LIBGCRYPT
gcry_sexp_release(gcryhash);
#endif
sign->type=privatekey->type;
if(!sign->dsa_sign && !sign->rsa_sign){
#ifdef HAVE_LIBGCRYPT
ssh_set_error(session,SSH_FATAL,"Signing : libcrypt error");
#elif HAVE_LIBCRYPTO
ssh_set_error(session,SSH_FATAL,"Signing : openssl error");
#endif
signature_free(sign);
return NULL;
}
@ -441,45 +656,87 @@ STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf, PRIVATE_KEY *privatekey
STRING *ssh_encrypt_rsa1(SSH_SESSION *session, STRING *data, PUBLIC_KEY *key){
int len=string_len(data);
#ifdef HAVE_LIBGCRYPT
STRING *ret;
gcry_sexp_t ret_sexp;
gcry_sexp_t data_sexp;
const char *tmp;
size_t size;
gcry_sexp_build(&data_sexp,NULL,"(data(flags pkcs1)(value %b))",len,data->string);
gcry_pk_encrypt(&ret_sexp,data_sexp,key->rsa_pub);
gcry_sexp_release(data_sexp);
data_sexp=gcry_sexp_find_token(ret_sexp,"a",0);
tmp=gcry_sexp_nth_data(data_sexp,1,&size);
if (*tmp == 0)
{
size--;
tmp++;
}
ret=string_new(size);
string_fill(ret,(char *)tmp,size);
gcry_sexp_release(ret_sexp);
#elif defined HAVE_LIBCRYPTO
int flen=RSA_size(key->rsa_pub);
STRING *ret=string_new(flen);
RSA_public_encrypt(len,data->string,ret->string,key->rsa_pub,
RSA_PKCS1_PADDING);
#endif
return ret;
}
/* this function signs the session id */
STRING *ssh_sign_session_id(SSH_SESSION *session, PRIVATE_KEY *privatekey){
SHACTX *ctx;
char hash[SHA_DIGEST_LEN];
SHACTX ctx;
unsigned char hash[SHA_DIGEST_LEN+1];
SIGNATURE *sign;
STRING *signature;
CRYPTO *crypto=session->current_crypto?session->current_crypto:session->next_crypto;
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t data_sexp;
#endif
ctx=sha1_init();
sha1_update(ctx,crypto->session_id,SHA_DIGEST_LENGTH);
sha1_final(hash,ctx);
sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN);
sha1_final(hash+1,ctx);
hash[0]=0;
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Hash being signed with dsa",hash,SHA_DIGEST_LENGTH);
ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN);
#endif
sign=malloc(sizeof(SIGNATURE));
switch(privatekey->type){
case TYPE_DSS:
sign->dsa_sign=DSA_do_sign(hash,SHA_DIGEST_LENGTH,privatekey->dsa_priv);
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&data_sexp,NULL,"%b",SHA_DIGEST_LEN+1,hash);
gcry_pk_sign(&sign->dsa_sign,data_sexp,privatekey->dsa_priv);
#elif defined HAVE_LIBCRYPTO
sign->dsa_sign=DSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->dsa_priv);
#ifdef DEBUG_CRYPTO
ssh_print_bignum("r",sign->dsa_sign->r);
ssh_print_bignum("s",sign->dsa_sign->s);
#endif
#endif
sign->rsa_sign=NULL;
break;
case TYPE_RSA:
sign->rsa_sign=RSA_do_sign(hash,SHA_DIGEST_LENGTH,privatekey->rsa_priv);
#ifdef HAVE_LIBGCRYPT
gcry_sexp_build(&data_sexp,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1);
gcry_pk_sign(&sign->rsa_sign,data_sexp,privatekey->rsa_priv);
#elif defined HAVE_LIBCRYPTO
sign->rsa_sign=RSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->rsa_priv);
#endif
sign->dsa_sign=NULL;
break;
}
#ifdef HAVE_LIBGCRYPT
gcry_sexp_release(data_sexp);
#endif
sign->type=privatekey->type;
if(!sign->dsa_sign && !sign->rsa_sign){
#ifdef HAVE_LIBGCRYPT
ssh_set_error(session,SSH_FATAL,"Signing : libgcrypt error");
#elif defined HAVE_LIBCRYPTO
ssh_set_error(session,SSH_FATAL,"Signing : openssl error");
#endif
signature_free(sign);
return NULL;
}

Просмотреть файл

@ -32,6 +32,7 @@ MA 02111-1307, USA. */
#include "libssh/ssh2.h"
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
static SSH_MESSAGE *message_new(SSH_SESSION *session){
SSH_MESSAGE *msg=session->ssh_message;

Просмотреть файл

@ -32,7 +32,7 @@ MA 02111-1307, USA. */
#include "libssh/crypto.h"
/* XXX include selected mac size */
static int macsize=SHA_DIGEST_LENGTH;
static int macsize=SHA_DIGEST_LEN;
/* completeread will read blocking until len bytes have been read */
static int completeread(int fd, void *buffer, int len){
@ -55,7 +55,7 @@ static int completeread(int fd, void *buffer, int len){
static int packet_read2(SSH_SESSION *session){
u32 len;
void *packet=NULL;
char mac[30];
unsigned char mac[30];
char buffer[16];
int be_read,i;
int to_be_read;
@ -316,7 +316,7 @@ static int packet_send2(SSH_SESSION *session){
u32 finallen;
u8 padding;
u32 currentlen=buffer_get_len(session->out_buffer);
char *hmac;
unsigned char *hmac;
int ret=0;
unsigned int blocksize=(session->current_crypto?session->current_crypto->out_cipher->blocksize:8);
ssh_say(3,"Writing on the wire a packet having %ld bytes before",currentlen);

Просмотреть файл

@ -27,10 +27,10 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "libssh/libssh.h"
#include "libssh/server.h"
#include "libssh/ssh2.h"

Просмотреть файл

@ -22,6 +22,7 @@
/* ssh_new() returns a newly allocated SSH_SESSION structure pointer */
#include <string.h>
#include <stdlib.h>
#include "libssh/libssh.h"
#include "libssh/priv.h"
#include "libssh/server.h"

Просмотреть файл

@ -22,6 +22,7 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>

Просмотреть файл

@ -26,6 +26,7 @@ MA 02111-1307, USA. */
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>
SFTP_CLIENT_MESSAGE *sftp_get_client_message(SFTP_SESSION *sftp){
SFTP_PACKET *packet=sftp_packet_read(sftp);

Просмотреть файл

@ -26,7 +26,7 @@ MA 02111-1307, USA. */
#include <string.h>
#include "libssh/priv.h"
STRING *string_new(u32 size){
STRING *string_new(unsigned int size){
STRING *str=malloc(size + 4);
str->size=htonl(size);
return str;

Просмотреть файл

@ -27,8 +27,178 @@ MA 02111-1307, USA. */
#include "libssh/priv.h"
#include "libssh/crypto.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef OPENSSL_CRYPTO
#ifdef HAVE_LIBGCRYPT
#include <gcrypt.h>
SHACTX sha1_init(){
SHACTX ret;
gcry_md_open(&ret,GCRY_MD_SHA1,GCRY_MD_FLAG_SECURE);
return ret;
}
void sha1_update(SHACTX c, const void *data, unsigned long len){
gcry_md_write(c,data,len);
}
void sha1_final(unsigned char *md,SHACTX c){
gcry_md_final(c);
memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN);
gcry_md_close(c);
}
void sha1(unsigned char *digest,int len,unsigned char *hash){
gcry_md_hash_buffer(GCRY_MD_SHA1,hash,digest,len);
}
MD5CTX md5_init(){
MD5CTX ret;
gcry_md_open(&ret,GCRY_MD_MD5,GCRY_MD_FLAG_SECURE);
return ret;
}
void md5_update(MD5CTX c, const void *data, unsigned long len){
gcry_md_write(c,data,len);
}
void md5_final(unsigned char *md,MD5CTX c){
gcry_md_final(c);
memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN);
gcry_md_close(c);
}
HMACCTX hmac_init(const void *key, int len,int type){
HMACCTX c;
switch(type){
case HMAC_SHA1:
gcry_md_open(&c,GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE);
break;
case HMAC_MD5:
gcry_md_open(&c,GCRY_MD_MD5, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE);
break;
default:
c=NULL;
}
gcry_md_setkey(c,key,len);
return c;
}
void hmac_update(HMACCTX c, const void *data, unsigned long len){
gcry_md_write(c,data,len);
}
void hmac_final(HMACCTX c,unsigned char *hashmacbuf,unsigned int *len){
*len = gcry_md_get_algo_dlen(gcry_md_get_algo(c));
memcpy(hashmacbuf, gcry_md_read(c, 0), *len);
gcry_md_close(c);
}
static void alloc_key(struct crypto_struct *cipher){
cipher->key=malloc(cipher->keylen);
}
/* the wrapper functions for blowfish */
static void blowfish_set_key(struct crypto_struct *cipher, void *key, void *IV){
if(!cipher->key){
alloc_key(cipher);
gcry_cipher_open(&cipher->key[0],GCRY_CIPHER_BLOWFISH,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
gcry_cipher_setkey(cipher->key[0],key,16);
gcry_cipher_setiv(cipher->key[0],IV,8);
}
}
static void blowfish_encrypt(struct crypto_struct *cipher, void *in, void *out,unsigned long len){
gcry_cipher_encrypt(cipher->key[0],out,len,in,len);
}
static void blowfish_decrypt(struct crypto_struct *cipher, void *in, void *out, unsigned long len){
gcry_cipher_decrypt(cipher->key[0],out,len,in,len);
}
static void aes_set_key(struct crypto_struct *cipher, void *key, void *IV){
if(!cipher->key){
alloc_key(cipher);
switch(cipher->keysize){
case 128:
gcry_cipher_open(&cipher->key[0],GCRY_CIPHER_AES128,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
break;
case 192:
gcry_cipher_open(&cipher->key[0],GCRY_CIPHER_AES192,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
break;
case 256:
gcry_cipher_open(&cipher->key[0],GCRY_CIPHER_AES256,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
break;
}
gcry_cipher_setkey(cipher->key[0],key,cipher->keysize/8);
gcry_cipher_setiv(cipher->key[0], IV, 16);
}
}
static void aes_encrypt(struct crypto_struct *cipher, void *in, void *out, unsigned long len){
gcry_cipher_encrypt(cipher->key[0],out,len,in,len);
}
static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out,unsigned long len){
gcry_cipher_decrypt(cipher->key[0],out,len,in,len);
}
static void des3_set_key(struct crypto_struct *cipher, void *key, void *IV){
if(!cipher->key){
alloc_key(cipher);
gcry_cipher_open(&cipher->key[0],GCRY_CIPHER_3DES,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
gcry_cipher_setkey(cipher->key[0],key,24);
gcry_cipher_setiv(cipher->key[0],IV,8);
}
}
static void des3_encrypt(struct crypto_struct *cipher, void *in, void *out,
unsigned long len){
gcry_cipher_encrypt(cipher->key[0],out,len,in,len);
}
static void des3_decrypt(struct crypto_struct *cipher, void *in, void *out,
unsigned long len){
gcry_cipher_decrypt(cipher->key[0],out,len,in,len);
}
static void des3_1_set_key(struct crypto_struct *cipher, void *key, void *IV){
if(!cipher->key){
alloc_key(cipher);
gcry_cipher_open(&cipher->key[0],GCRY_CIPHER_DES,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
gcry_cipher_setkey(cipher->key[0],key,8);
gcry_cipher_setiv(cipher->key[0],IV,8);
gcry_cipher_open(&cipher->key[1],GCRY_CIPHER_DES,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
gcry_cipher_setkey(cipher->key[1],key+8,8);
gcry_cipher_setiv(cipher->key[1],IV+8,8);
gcry_cipher_open(&cipher->key[2],GCRY_CIPHER_DES,GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_SECURE);
gcry_cipher_setkey(cipher->key[2],key+16,8);
gcry_cipher_setiv(cipher->key[2],IV+16,8);
}
}
static void des3_1_encrypt(struct crypto_struct *cipher, void *in, void *out,
unsigned long len){
gcry_cipher_encrypt(cipher->key[0],out,len,in,len);
gcry_cipher_decrypt(cipher->key[1],in,len,out,len);
gcry_cipher_encrypt(cipher->key[2],out,len,in,len);
}
static void des3_1_decrypt(struct crypto_struct *cipher, void *in, void *out,
unsigned long len){
gcry_cipher_decrypt(cipher->key[2],out,len,in,len);
gcry_cipher_encrypt(cipher->key[1],in,len,out,len);
gcry_cipher_decrypt(cipher->key[0],out,len,in,len);
}
/* the table of supported ciphers */
static struct crypto_struct ssh_ciphertab[]={
{ "blowfish-cbc", 8 ,sizeof (gcry_cipher_hd_t),NULL,128,blowfish_set_key,blowfish_set_key,blowfish_encrypt, blowfish_decrypt},
{ "aes128-cbc",16,sizeof(gcry_cipher_hd_t),NULL,128,aes_set_key,aes_set_key,aes_encrypt,aes_decrypt},
{ "aes192-cbc",16,sizeof(gcry_cipher_hd_t),NULL,192,aes_set_key,aes_set_key,aes_encrypt,aes_decrypt},
{ "aes256-cbc",16,sizeof(gcry_cipher_hd_t),NULL,256,aes_set_key,aes_set_key,aes_encrypt,aes_decrypt},
{ "3des-cbc",8,sizeof(gcry_cipher_hd_t),NULL,192,des3_set_key,
des3_set_key,des3_encrypt, des3_decrypt},
{ "3des-cbc-ssh1",8,sizeof(gcry_cipher_hd_t)*3,NULL,192,des3_1_set_key,
des3_1_set_key,des3_1_encrypt, des3_1_decrypt},
{ NULL,0,0,NULL,0,NULL,NULL,NULL}
};
#elif defined HAVE_LIBCRYPTO
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/dsa.h>
@ -43,22 +213,24 @@ MA 02111-1307, USA. */
#define HAS_BLOWFISH
#include <openssl/blowfish.h>
#endif
#ifdef HAVE_OPENSSL_DES_H
#define HAS_DES
#include <openssl/des.h>
#endif
#if (OPENSSL_VERSION_NUMBER<0x009070000)
#define OLD_CRYPTO
#endif
SHACTX *sha1_init(){
SHACTX *c=malloc(sizeof(SHACTX));
SHACTX sha1_init(){
SHACTX c=malloc(sizeof(*c));
SHA1_Init(c);
return c;
}
void sha1_update(SHACTX *c, const void *data, unsigned long len){
void sha1_update(SHACTX c, const void *data, unsigned long len){
SHA1_Update(c,data,len);
}
void sha1_final(unsigned char *md,SHACTX *c){
void sha1_final(unsigned char *md,SHACTX c){
SHA1_Final(md,c);
free(c);
}
@ -66,21 +238,21 @@ void sha1(unsigned char *digest,int len,unsigned char *hash){
SHA1(digest,len,hash);
}
MD5CTX *md5_init(){
MD5CTX *c=malloc(sizeof(MD5CTX));
MD5CTX md5_init(){
MD5CTX c=malloc(sizeof(MD5CTX));
MD5_Init(c);
return c;
}
void md5_update(MD5CTX *c, const void *data, unsigned long len){
void md5_update(MD5CTX c, const void *data, unsigned long len){
MD5_Update(c,data,len);
}
void md5_final(unsigned char *md,MD5CTX *c){
void md5_final(unsigned char *md,MD5CTX c){
MD5_Final(md,c);
free(c);
}
HMACCTX *hmac_init(const void *key, int len,int type){
HMAC_CTX *ctx;
HMACCTX hmac_init(const void *key, int len,int type){
HMACCTX ctx;
ctx=malloc(sizeof(HMAC_CTX));
#ifndef OLD_CRYPTO
HMAC_CTX_init(ctx); // openssl 0.9.7 requires it.
@ -98,10 +270,10 @@ HMACCTX *hmac_init(const void *key, int len,int type){
}
return ctx;
}
void hmac_update(HMACCTX *ctx,const void *data, unsigned long len){
void hmac_update(HMACCTX ctx,const void *data, unsigned long len){
HMAC_Update(ctx,data,len);
}
void hmac_final(HMACCTX *ctx,unsigned char *hashmacbuf,int *len){
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len){
HMAC_Final(ctx,hashmacbuf,len);
#ifndef OLD_CRYPTO
HMAC_CTX_cleanup(ctx);
@ -152,7 +324,7 @@ static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out, unsig
AES_cbc_encrypt(in,out,len,cipher->key,IV,AES_DECRYPT);
}
#endif
#ifdef HAS_DES
static void des3_set_key(struct crypto_struct *cipher, void *key){
if(!cipher->key){
alloc_key(cipher);
@ -205,10 +377,8 @@ static void des3_1_decrypt(struct crypto_struct *cipher, void *in, void *out,
ssh_print_hexa("decrypt IV after",IV,24);
#endif
}
#endif
/* the table of supported ciphers */
static struct crypto_struct ssh_ciphertab[]={
#ifdef HAS_BLOWFISH
@ -223,10 +393,12 @@ static struct crypto_struct ssh_ciphertab[]={
{ "aes256-cbc",16,sizeof(AES_KEY),NULL,256,aes_set_encrypt_key,
aes_set_decrypt_key,aes_encrypt,aes_decrypt},
#endif
#ifdef HAS_DES
{ "3des-cbc",8,sizeof(DES_key_schedule)*3,NULL,192,des3_set_key,
des3_set_key,des3_encrypt, des3_decrypt},
{ "3des-cbc-ssh1",8,sizeof(DES_key_schedule)*3,NULL,192,des3_set_key,
des3_set_key,des3_1_encrypt, des3_1_decrypt},
#endif
{ NULL,0,0,NULL,0,NULL,NULL,NULL}
};
#endif /* OPENSSL_CRYPTO */
@ -240,9 +412,17 @@ struct crypto_struct *cipher_new(int offset){
}
void cipher_free(struct crypto_struct *cipher){
#ifdef HAVE_LIBGCRYPT
int i;
#endif
if(cipher->key){
// destroy the key
#ifdef HAVE_LIBGCRYPT
for (i=0;i<cipher->keylen/sizeof (gcry_cipher_hd_t);i++)
gcry_cipher_close(cipher->key[i]);
#elif defined HAVE_LIBCRYPTO
/* destroy the key */
memset(cipher->key,0,cipher->keylen);
#endif
free(cipher->key);
}
free(cipher);

Просмотреть файл

@ -358,7 +358,7 @@ int main(int argc, char **argv){
char *banner;
int state;
char buf[10];
char hash[MD5_DIGEST_LEN];
unsigned char hash[MD5_DIGEST_LEN];
options=ssh_options_new();
if(ssh_options_getopt(options,&argc, argv))

Просмотреть файл

@ -24,6 +24,7 @@ MA 02111-1307, USA. */
#include <libssh/server.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int auth_password(char *user, char *password){
if(strcmp(user,"aris"))