5772795 [rkeene@sledge /home/rkeene/projects/libssh-win32/v0.11/src/libssh-0.11-win32/libssh]$ cat -n wrapper.c
  1 /* wrapper.c */
  2 /* wrapping functions for crypto functions. */
  3 /* why a wrapper ? let's say you want to port libssh from libcrypto of openssl to libfoo */
  4 /* you are going to spend hours to remove every references to SHA1_Update() to libfoo_sha1_update */
  5 /* after the work is finished, you're going to have only this file to modify */
  6 /* it's not needed to say that your modifications are welcome */
  7 
  8 /*
  9 Copyright 2003 Aris Adamantiadis
 10 
 11 This file is part of the SSH Library
 12 
 13 The SSH Library is free software; you can redistribute it and/or modify
 14 it under the terms of the GNU Lesser General Public License as published by
 15 the Free Software Foundation; either version 2.1 of the License, or (at your
 16 option) any later version.
 17 
 18 The SSH Library is distributed in the hope that it will be useful, but
 19 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 20 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 21 License for more details.
 22 
 23 You should have received a copy of the GNU Lesser General Public License
 24 along with the SSH Library; see the file COPYING.  If not, write to
 25 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 26 MA 02111-1307, USA. */
 27 
 28 #include "libssh/priv.h"
 29 #include "libssh/crypto.h"
 30 #include <string.h>
 31 #ifdef OPENSSL_CRYPTO
 32 #include <openssl/sha.h>
 33 #include <openssl/md5.h>
 34 #include <openssl/dsa.h>
 35 #include <openssl/rsa.h>
 36 #include <openssl/hmac.h>
 37 #include <openssl/opensslv.h>
 38 #ifdef HAVE_OPENSSL_AES_H
 39 #define HAS_AES
 40 #include <openssl/aes.h>
 41 #endif
 42 #ifdef HAVE_OPENSSL_BLOWFISH_H
 43 #define HAS_BLOWFISH
 44 #include <openssl/blowfish.h>
 45 #endif
 46 #if (OPENSSL_VERSION_NUMBER<0x009070000)
 47 #define OLD_CRYPTO
 48 #endif
 49 
 50 SHACTX *sha1_init(){
 51     SHACTX *c=malloc(sizeof(SHACTX));
 52     SHA1_Init(c);
 53     return c;
 54 }
 55 void sha1_update(SHACTX *c, const void *data, unsigned long len){
 56     SHA1_Update(c,data,len);
 57 }
 58 void sha1_final(unsigned char *md,SHACTX *c){
 59     SHA1_Final(md,c);
 60     free(c);
 61 }
 62 void sha1(unsigned char *digest,int len,unsigned char *hash){
 63     SHA1(digest,len,hash);
 64 }
 65 
 66 MD5CTX *md5_init(){
 67     MD5CTX *c=malloc(sizeof(MD5CTX));
 68     MD5_Init(c);
 69     return c;
 70 }
 71 void md5_update(MD5CTX *c, const void *data, unsigned long len){
 72     MD5_Update(c,data,len);
 73 }
 74 void md5_final(unsigned char *md,MD5CTX *c){
 75     MD5_Final(md,c);
 76     free(c);
 77 }
 78 
 79 HMACCTX *hmac_init(const void *key, int len,int type){
 80     HMAC_CTX *ctx;
 81     ctx=malloc(sizeof(HMAC_CTX));
 82 #ifndef OLD_CRYPTO
 83     HMAC_CTX_init(ctx); // openssl 0.9.7 requires it.
 84 #endif
 85     switch(type){
 86         case HMAC_SHA1:
 87             HMAC_Init(ctx,key,len,EVP_sha1());
 88             break;
 89         case HMAC_MD5:
 90             HMAC_Init(ctx,key,len,EVP_md5());
 91             break;
 92         default:
 93             free(ctx);
 94             ctx=NULL;
 95         }
 96     return ctx;
 97 }
 98 void hmac_update(HMACCTX *ctx,const void *data, unsigned long len){
 99     HMAC_Update(ctx,data,len);
100 }
101 void hmac_final(HMACCTX *ctx,unsigned char *hashmacbuf,int *len){
102    HMAC_Final(ctx,hashmacbuf,len);
103 #ifndef OLD_CRYPTO
104    HMAC_CTX_cleanup(ctx);
105 #else
106    HMAC_cleanup(ctx);
107 #endif
108    free(ctx);
109 }
110 
111 static void alloc_key(struct crypto_struct *cipher){
112     cipher->key=malloc(cipher->keylen);
113 }
114 
115 #ifdef HAS_BLOWFISH
116 /* the wrapper functions for blowfish */
117 static void blowfish_set_key(struct crypto_struct *cipher, void *key){
118     if(!cipher->key){
119         alloc_key(cipher);
120         BF_set_key(cipher->key,16,key);
121     }
122 }
123 
124 static void blowfish_encrypt(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV){
125     BF_cbc_encrypt(in,out,len,cipher->key,IV,BF_ENCRYPT);
126 }
127 
128 static void blowfish_decrypt(struct crypto_struct *cipher, void *in, void *out,unsigned long len,void *IV){
129     BF_cbc_encrypt(in,out,len,cipher->key,IV,BF_DECRYPT);
130 }
131 #endif
132 #ifdef HAS_AES
133 static void aes_set_encrypt_key(struct crypto_struct *cipher, void *key){
134     if(!cipher->key){
135         alloc_key(cipher);
136         AES_set_encrypt_key(key,cipher->keysize,cipher->key);
137     }
138 }
139 static void aes_set_decrypt_key(struct crypto_struct *cipher, void *key){
140     if(!cipher->key){
141         alloc_key(cipher);
142         AES_set_decrypt_key(key,cipher->keysize,cipher->key);
143     }
144 }
145 static void aes_encrypt(struct crypto_struct *cipher, void *in, void *out, unsigned long len, void *IV){
146     AES_cbc_encrypt(in,out,len,cipher->key,IV,AES_ENCRYPT);
147 }
148 static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out, unsigned long len, void *IV){
149     AES_cbc_encrypt(in,out,len,cipher->key,IV,AES_DECRYPT);
150 }
151 #endif
152 /* the table of supported ciphers */
153 static struct crypto_struct ssh_ciphertab[]={
154 #ifdef HAS_BLOWFISH
155     { "blowfish-cbc", 8 ,sizeof (BF_KEY),NULL,128,blowfish_set_key,blowfish_set_key,blowfish_encrypt, blowfish_decrypt},
156 #endif
157 #ifdef HAS_AES
158     { "aes128-cbc",16,sizeof(AES_KEY),NULL,128,aes_set_encrypt_key,aes_set_decrypt_key,aes_encrypt,aes_decrypt},
159     { "aes192-cbc",16,sizeof(AES_KEY),NULL,192,aes_set_encrypt_key,aes_set_decrypt_key,aes_encrypt,aes_decrypt},
160     { "aes256-cbc",16,sizeof(AES_KEY),NULL,256,aes_set_encrypt_key,aes_set_decrypt_key,aes_encrypt,aes_decrypt},
161 #endif
162     { NULL,0,0,NULL,0,NULL,NULL,NULL}
163 };
164 #endif /* OPENSSL_CRYPTO */
165 
166 /* it allocates a new cipher structure based on its offset into the global table */
167 struct crypto_struct *cipher_new(int offset){
168     struct crypto_struct *cipher=malloc(sizeof(struct crypto_struct));
169     /* note the memcpy will copy the pointers : so, you shouldn't free them */
170     memcpy(cipher,&ssh_ciphertab[offset],sizeof(*cipher));
171     return cipher;
172 }
173 
174 void cipher_free(struct crypto_struct *cipher){
175     if(cipher->key){
176         // destroy the key
177         memset(cipher->key,0,cipher->keylen);
178         free(cipher->key);
179     }
180     free(cipher);
181 }
182 
183 CRYPTO *crypto_new(){
184     CRYPTO *crypto=malloc(sizeof (CRYPTO));
185     memset(crypto,0,sizeof(*crypto));
186     return crypto;
187 }
188 
189 void crypto_free(CRYPTO *crypto){
190     if(crypto->server_pubkey)
191         free(crypto->server_pubkey);
192     if(crypto->in_cipher)
193         cipher_free(crypto->in_cipher);
194     if(crypto->out_cipher)
195         cipher_free(crypto->out_cipher);
196     if(crypto->e)
197         bignum_free(crypto->e);
198     if(crypto->f)
199         bignum_free(crypto->f);
200     if(crypto->x)
201         bignum_free(crypto->x);
202     if(crypto->k)
203         bignum_free(crypto->k);
204     /* lot of other things */
205     /* i'm lost in my own code. good work */
206     memset(crypto,0,sizeof(*crypto));
207     free(crypto);
208 }
209 
210 int crypt_set_algorithms(SSH_SESSION *session){
211     /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */
212     int i=0;
213     /* out */
214     char *wanted=session->client_kex.methods[KEX_CRYPT_C_S];
215     while(ssh_ciphertab[i].name && strcmp(wanted,ssh_ciphertab[i].name))
216         i++;
217     if(!ssh_ciphertab[i].name){
218         ssh_set_error((session->connected?session:NULL),SSH_FATAL,"Crypt_set_algorithms : no crypto algorithm function
	found for %s",wanted);
219         return -1;
220     }
221     ssh_say(2,"Set output algorithm %s\n",wanted);
222     session->next_crypto->out_cipher=cipher_new(i);
223     i=0;
224     /* in */
225     wanted=session->client_kex.methods[KEX_CRYPT_S_C];
226     while(ssh_ciphertab[i].name && strcmp(wanted,ssh_ciphertab[i].name))
227         i++;
228     if(!ssh_ciphertab[i].name){
229         ssh_set_error((session->connected?session:NULL),SSH_FATAL,"Crypt_set_algorithms : no crypto algorithm function
	found for %s",wanted);
230         return -1;
231     }
232     ssh_say(2,"Set input algorithm %s\n",wanted);
233     session->next_crypto->in_cipher=cipher_new(i);
234     
235     /* compression */
236     if(strstr(session->client_kex.methods[KEX_COMP_C_S],"zlib"))
237         session->next_crypto->do_compress_out=1;
238     if(strstr(session->client_kex.methods[KEX_COMP_S_C],"zlib"))
239         session->next_crypto->do_compress_in=1;
240     return 0;
241 }
5772796 [rkeene@sledge /home/rkeene/projects/libssh-win32/v0.11/src/libssh-0.11-win32/libssh]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2005-03-04 19:54:59