mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
Peter Schellenbach's patch: re-implement the PuTTY cryptographic
functions as calls to the MS Crypto API. Not integrated into the Makefile yet, but should eventually allow building of an SSH-enabled PuTTY which contains no native crypto code, so it can be used everywhere (and anyone who can get the MS encryption pack can still use the SSH parts). [originally from svn r425]
This commit is contained in:
parent
e32eae7db1
commit
9922072a8d
424
mscrypto.c
Normal file
424
mscrypto.c
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
#define _WIN32_WINNT 0x0400
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
|
#include "ssh.h"
|
||||||
|
|
||||||
|
void fatalbox(char *fmt, ...);
|
||||||
|
|
||||||
|
static HCRYPTKEY create_des_key(unsigned char *key);
|
||||||
|
|
||||||
|
|
||||||
|
HCRYPTPROV hCryptProv;
|
||||||
|
HCRYPTKEY hDESKey[2][3] = {{0,0,0},{0,0,0}}; /* global for now */
|
||||||
|
|
||||||
|
|
||||||
|
/* use Microsoft Enhanced Cryptographic Service Provider */
|
||||||
|
#define CSP MS_ENHANCED_PROV
|
||||||
|
|
||||||
|
|
||||||
|
static BYTE PrivateKeyWithExponentOfOne[] =
|
||||||
|
{
|
||||||
|
0x07, 0x02, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00,
|
||||||
|
0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0xAB, 0xEF, 0xFA, 0xC6,
|
||||||
|
0x7D, 0xE8, 0xDE, 0xFB, 0x68, 0x38, 0x09, 0x92,
|
||||||
|
0xD9, 0x42, 0x7E, 0x6B, 0x89, 0x9E, 0x21, 0xD7,
|
||||||
|
0x52, 0x1C, 0x99, 0x3C, 0x17, 0x48, 0x4E, 0x3A,
|
||||||
|
0x44, 0x02, 0xF2, 0xFA, 0x74, 0x57, 0xDA, 0xE4,
|
||||||
|
0xD3, 0xC0, 0x35, 0x67, 0xFA, 0x6E, 0xDF, 0x78,
|
||||||
|
0x4C, 0x75, 0x35, 0x1C, 0xA0, 0x74, 0x49, 0xE3,
|
||||||
|
0x20, 0x13, 0x71, 0x35, 0x65, 0xDF, 0x12, 0x20,
|
||||||
|
0xF5, 0xF5, 0xF5, 0xC1, 0xED, 0x5C, 0x91, 0x36,
|
||||||
|
0x75, 0xB0, 0xA9, 0x9C, 0x04, 0xDB, 0x0C, 0x8C,
|
||||||
|
0xBF, 0x99, 0x75, 0x13, 0x7E, 0x87, 0x80, 0x4B,
|
||||||
|
0x71, 0x94, 0xB8, 0x00, 0xA0, 0x7D, 0xB7, 0x53,
|
||||||
|
0xDD, 0x20, 0x63, 0xEE, 0xF7, 0x83, 0x41, 0xFE,
|
||||||
|
0x16, 0xA7, 0x6E, 0xDF, 0x21, 0x7D, 0x76, 0xC0,
|
||||||
|
0x85, 0xD5, 0x65, 0x7F, 0x00, 0x23, 0x57, 0x45,
|
||||||
|
0x52, 0x02, 0x9D, 0xEA, 0x69, 0xAC, 0x1F, 0xFD,
|
||||||
|
0x3F, 0x8C, 0x4A, 0xD0,
|
||||||
|
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
|
0x64, 0xD5, 0xAA, 0xB1,
|
||||||
|
0xA6, 0x03, 0x18, 0x92, 0x03, 0xAA, 0x31, 0x2E,
|
||||||
|
0x48, 0x4B, 0x65, 0x20, 0x99, 0xCD, 0xC6, 0x0C,
|
||||||
|
0x15, 0x0C, 0xBF, 0x3E, 0xFF, 0x78, 0x95, 0x67,
|
||||||
|
0xB1, 0x74, 0x5B, 0x60,
|
||||||
|
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------*
|
||||||
|
* Utility functions *
|
||||||
|
* ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
int crypto_startup() {
|
||||||
|
if(CryptAcquireContext(&hCryptProv, "Putty", CSP, PROV_RSA_FULL,
|
||||||
|
CRYPT_NEWKEYSET) == 0) {
|
||||||
|
if(GetLastError() == NTE_EXISTS) {
|
||||||
|
if(CryptAcquireContext(&hCryptProv, "Putty", CSP,
|
||||||
|
PROV_RSA_FULL, 0) == 0) {
|
||||||
|
return FALSE; /* failed to acquire context - probably
|
||||||
|
* don't have high encryption installed! */
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return FALSE; /* failed to acquire context - probably
|
||||||
|
* don't have high encryption installed! */
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void crypto_wrapup() {
|
||||||
|
int i, j;
|
||||||
|
for(i=0; i<2; i++) {
|
||||||
|
for(j=0; j<3; j++) {
|
||||||
|
if(hDESKey[i][j])
|
||||||
|
CryptDestroyKey(hDESKey[i][j]);
|
||||||
|
hDESKey[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hCryptProv)
|
||||||
|
CryptReleaseContext(hCryptProv, 0);
|
||||||
|
hCryptProv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------*
|
||||||
|
* Random number functions *
|
||||||
|
* ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
int random_byte(void) {
|
||||||
|
unsigned char b;
|
||||||
|
if(!CryptGenRandom(hCryptProv, 1, &b))
|
||||||
|
fatalbox("random number generator failure!");
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void random_add_noise(void *noise, int length) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
void random_init(void) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
void random_get_savedata(void **data, int *len) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
void noise_get_heavy(void (*func) (void *, int)) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
void noise_get_light(void (*func) (void *, int)) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
void noise_ultralight(DWORD data) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
void random_save_seed(void) {
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------*
|
||||||
|
* MD5 hash functions *
|
||||||
|
* ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
void MD5Init(struct MD5Context *ctx) {
|
||||||
|
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx->hHash))
|
||||||
|
fatalbox("Error during CryptBeginHash!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MD5Update(struct MD5Context *ctx,
|
||||||
|
unsigned char const *buf, unsigned len) {
|
||||||
|
if(CryptHashData(ctx->hHash, buf, len, 0) == 0)
|
||||||
|
fatalbox("Error during CryptHashSessionKey!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MD5Final(unsigned char digest[16], struct MD5Context *ctx) {
|
||||||
|
DWORD cb = 16;
|
||||||
|
if(CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &cb, 0) == 0)
|
||||||
|
fatalbox("Error during CryptGetHashParam!\n");
|
||||||
|
if(ctx->hHash)
|
||||||
|
CryptDestroyHash(ctx->hHash);
|
||||||
|
ctx->hHash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------*
|
||||||
|
* RSA public key functions *
|
||||||
|
* ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
int makekey(unsigned char *data, struct RSAKey *result,
|
||||||
|
unsigned char **keystr) {
|
||||||
|
|
||||||
|
unsigned char *p = data;
|
||||||
|
int i;
|
||||||
|
int w, b;
|
||||||
|
|
||||||
|
/* get size (bits) of modulus */
|
||||||
|
result->bits = 0;
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
result->bits = (result->bits << 8) + *p++;
|
||||||
|
|
||||||
|
/* get size (bits) of public exponent */
|
||||||
|
w = 0;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
w = (w << 8) + *p++;
|
||||||
|
b = (w+7)/8; /* bits -> bytes */
|
||||||
|
|
||||||
|
/* convert exponent to DWORD */
|
||||||
|
result->exponent = 0;
|
||||||
|
for (i=0; i<b; i++)
|
||||||
|
result->exponent = (result->exponent << 8) + *p++;
|
||||||
|
|
||||||
|
/* get size (bits) of modulus */
|
||||||
|
w = 0;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
w = (w << 8) + *p++;
|
||||||
|
result->bytes = b = (w+7)/8; /* bits -> bytes */
|
||||||
|
|
||||||
|
/* allocate buffer for modulus & copy it */
|
||||||
|
result->modulus = malloc(b);
|
||||||
|
memcpy(result->modulus, p, b);
|
||||||
|
|
||||||
|
/* update callers pointer */
|
||||||
|
if (keystr) *keystr = p; /* point at key string, second time */
|
||||||
|
|
||||||
|
return (p - data) + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
unsigned char *pKeybuf, *pKeyin;
|
||||||
|
HCRYPTKEY hRsaKey;
|
||||||
|
PUBLICKEYSTRUC *pBlob;
|
||||||
|
RSAPUBKEY *pRPK;
|
||||||
|
unsigned char *buf;
|
||||||
|
DWORD dlen;
|
||||||
|
DWORD bufsize;
|
||||||
|
|
||||||
|
/* allocate buffer for public key blob */
|
||||||
|
if((pBlob = malloc(sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) +
|
||||||
|
rsakey->bytes)) == NULL)
|
||||||
|
fatalbox("Out of memory");
|
||||||
|
|
||||||
|
/* allocate buffer for message encryption block */
|
||||||
|
bufsize = (length + rsakey->bytes) << 1;
|
||||||
|
if((buf = malloc(bufsize)) == NULL)
|
||||||
|
fatalbox("Out of memory");
|
||||||
|
|
||||||
|
/* construct public key blob from host public key */
|
||||||
|
pKeybuf = ((unsigned char*)pBlob) + sizeof(PUBLICKEYSTRUC) +
|
||||||
|
sizeof(RSAPUBKEY);
|
||||||
|
pKeyin = ((unsigned char*)rsakey->modulus);
|
||||||
|
/* change big endian to little endian */
|
||||||
|
for(i=0; i<rsakey->bytes; i++)
|
||||||
|
pKeybuf[i] = pKeyin[rsakey->bytes-i-1];
|
||||||
|
pBlob->bType = PUBLICKEYBLOB;
|
||||||
|
pBlob->bVersion = 0x02;
|
||||||
|
pBlob->reserved = 0;
|
||||||
|
pBlob->aiKeyAlg = CALG_RSA_KEYX;
|
||||||
|
pRPK = (RSAPUBKEY*)(((unsigned char*)pBlob) + sizeof(PUBLICKEYSTRUC));
|
||||||
|
pRPK->magic = 0x31415352; /* "RSA1" */
|
||||||
|
pRPK->bitlen = rsakey->bits;
|
||||||
|
pRPK->pubexp = rsakey->exponent;
|
||||||
|
|
||||||
|
/* import public key blob into key container */
|
||||||
|
if(CryptImportKey(hCryptProv, (void*)pBlob,
|
||||||
|
sizeof(PUBLICKEYSTRUC)+sizeof(RSAPUBKEY)+rsakey->bytes,
|
||||||
|
0, 0, &hRsaKey) == 0)
|
||||||
|
fatalbox("Error importing RSA key!");
|
||||||
|
|
||||||
|
/* copy message into buffer */
|
||||||
|
memcpy(buf, data, length);
|
||||||
|
dlen = length;
|
||||||
|
|
||||||
|
/* using host public key, encrypt the message */
|
||||||
|
if(CryptEncrypt(hRsaKey, 0, TRUE, 0, buf, &dlen, bufsize) == 0)
|
||||||
|
fatalbox("Error encrypting using RSA key!");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For some strange reason, Microsoft CryptEncrypt using public
|
||||||
|
* key, returns the cyphertext in backwards (little endian)
|
||||||
|
* order, so reverse it!
|
||||||
|
*/
|
||||||
|
for(i = 0; i < (int)dlen; i++)
|
||||||
|
data[i] = buf[dlen - i - 1]; /* make it big endian */
|
||||||
|
|
||||||
|
CryptDestroyKey(hRsaKey);
|
||||||
|
free(buf);
|
||||||
|
free(pBlob);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rsastr_len(struct RSAKey *key) {
|
||||||
|
return 2 * (sizeof(DWORD) + key->bytes) + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rsastr_fmt(char *str, struct RSAKey *key) {
|
||||||
|
|
||||||
|
int len = 0, i;
|
||||||
|
|
||||||
|
sprintf(str+len, "%04x", key->exponent);
|
||||||
|
len += strlen(str+len);
|
||||||
|
|
||||||
|
str[len++] = '/';
|
||||||
|
for (i=1; i<key->bytes; i++) {
|
||||||
|
sprintf(str+len, "%02x", key->modulus[i]);
|
||||||
|
len += strlen(str+len);
|
||||||
|
}
|
||||||
|
str[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------*
|
||||||
|
* DES encryption / decryption functions *
|
||||||
|
* ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
void des3_sesskey(unsigned char *key) {
|
||||||
|
int i, j;
|
||||||
|
for(i = 0; i < 2; i++) {
|
||||||
|
for(j = 0; j < 3; j++) {
|
||||||
|
hDESKey[i][j] = create_des_key(key + (j * 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void des3_encrypt_blk(unsigned char *blk, int len) {
|
||||||
|
|
||||||
|
DWORD dlen;
|
||||||
|
dlen = len;
|
||||||
|
|
||||||
|
if(CryptEncrypt(hDESKey[0][0], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
|
||||||
|
fatalbox("Error encrypting block!\n");
|
||||||
|
if(CryptDecrypt(hDESKey[0][1], 0, FALSE, 0, blk, &dlen) == 0)
|
||||||
|
fatalbox("Error encrypting block!\n");
|
||||||
|
if(CryptEncrypt(hDESKey[0][2], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
|
||||||
|
fatalbox("Error encrypting block!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void des3_decrypt_blk(unsigned char *blk, int len) {
|
||||||
|
DWORD dlen;
|
||||||
|
dlen = len;
|
||||||
|
|
||||||
|
if(CryptDecrypt(hDESKey[1][2], 0, FALSE, 0, blk, &dlen) == 0)
|
||||||
|
fatalbox("Error decrypting block!\n");
|
||||||
|
if(CryptEncrypt(hDESKey[1][1], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
|
||||||
|
fatalbox("Error decrypting block!\n");
|
||||||
|
if(CryptDecrypt(hDESKey[1][0], 0, FALSE, 0, blk, &dlen) == 0)
|
||||||
|
fatalbox("Error decrypting block!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ssh_cipher ssh_3des = {
|
||||||
|
des3_sesskey,
|
||||||
|
des3_encrypt_blk,
|
||||||
|
des3_decrypt_blk
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void des_sesskey(unsigned char *key) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 2; i++) {
|
||||||
|
hDESKey[i][0] = create_des_key(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void des_encrypt_blk(unsigned char *blk, int len) {
|
||||||
|
DWORD dlen;
|
||||||
|
dlen = len;
|
||||||
|
if(CryptEncrypt(hDESKey[0][0], 0, FALSE, 0, blk, &dlen, len + 8) == 0)
|
||||||
|
fatalbox("Error encrypting block!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void des_decrypt_blk(unsigned char *blk, int len) {
|
||||||
|
DWORD dlen;
|
||||||
|
dlen = len;
|
||||||
|
if(CryptDecrypt(hDESKey[1][0], 0, FALSE, 0, blk, &dlen) == 0)
|
||||||
|
fatalbox("Error decrypting block!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ssh_cipher ssh_des = {
|
||||||
|
des_sesskey,
|
||||||
|
des_encrypt_blk,
|
||||||
|
des_decrypt_blk
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static HCRYPTKEY create_des_key(unsigned char *key) {
|
||||||
|
|
||||||
|
HCRYPTKEY hSessionKey, hPrivateKey;
|
||||||
|
DWORD dlen = 8;
|
||||||
|
BLOBHEADER *pbh;
|
||||||
|
char buf[sizeof(BLOBHEADER) + sizeof(ALG_ID) + 256];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need special private key to encrypt session key so we can
|
||||||
|
* import session key, since only encrypted session keys can be
|
||||||
|
* imported
|
||||||
|
*/
|
||||||
|
if(CryptImportKey(hCryptProv, PrivateKeyWithExponentOfOne,
|
||||||
|
sizeof(PrivateKeyWithExponentOfOne),
|
||||||
|
0, 0, &hPrivateKey) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* now encrypt session key using special private key */
|
||||||
|
memcpy(buf + sizeof(BLOBHEADER) + sizeof(ALG_ID), key, 8);
|
||||||
|
if(CryptEncrypt(hPrivateKey, 0, TRUE, 0,
|
||||||
|
buf + sizeof(BLOBHEADER) + sizeof(ALG_ID),
|
||||||
|
&dlen, 256) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* build session key blob */
|
||||||
|
pbh = (BLOBHEADER*)buf;
|
||||||
|
pbh->bType = SIMPLEBLOB;
|
||||||
|
pbh->bVersion = 0x02;
|
||||||
|
pbh->reserved = 0;
|
||||||
|
pbh->aiKeyAlg = CALG_DES;
|
||||||
|
*((ALG_ID*)(buf+sizeof(BLOBHEADER))) = CALG_RSA_KEYX;
|
||||||
|
|
||||||
|
/* import session key into key container */
|
||||||
|
if(CryptImportKey(hCryptProv, buf,
|
||||||
|
dlen + sizeof(BLOBHEADER) + sizeof(ALG_ID),
|
||||||
|
hPrivateKey, 0, &hSessionKey) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(hPrivateKey)
|
||||||
|
CryptDestroyKey(hPrivateKey);
|
||||||
|
|
||||||
|
return hSessionKey;
|
||||||
|
|
||||||
|
}
|
8
putty.h
8
putty.h
@ -323,6 +323,14 @@ unsigned char xlat_kbd2tty(unsigned char c);
|
|||||||
unsigned char xlat_tty2scr(unsigned char c);
|
unsigned char xlat_tty2scr(unsigned char c);
|
||||||
unsigned char xlat_latkbd2win(unsigned char c);
|
unsigned char xlat_latkbd2win(unsigned char c);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exports from mscrypto.c
|
||||||
|
*/
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
int crypto_startup();
|
||||||
|
void crypto_wrapup();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A debug system.
|
* A debug system.
|
||||||
*/
|
*/
|
||||||
|
3
scp.c
3
scp.c
@ -814,6 +814,9 @@ int main(int argc, char *argv[])
|
|||||||
ssh_send_eof();
|
ssh_send_eof();
|
||||||
ssh_recv(&ch, 1);
|
ssh_recv(&ch, 1);
|
||||||
}
|
}
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
crypto_wrapup();
|
||||||
|
#endif
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
random_save_seed();
|
random_save_seed();
|
||||||
|
|
||||||
|
8
scp.h
8
scp.h
@ -19,3 +19,11 @@ int ssh_recv(unsigned char *buf, int len);
|
|||||||
void ssh_send(unsigned char *buf, int len);
|
void ssh_send(unsigned char *buf, int len);
|
||||||
void ssh_send_eof(void);
|
void ssh_send_eof(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exports from mscrypto.c
|
||||||
|
*/
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
int crypto_startup();
|
||||||
|
void crypto_wrapup();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
21
scpssh.c
21
scpssh.c
@ -121,8 +121,15 @@ next_packet:
|
|||||||
pktin.length = len;
|
pktin.length = len;
|
||||||
if (pktin.maxlen < biglen) {
|
if (pktin.maxlen < biglen) {
|
||||||
pktin.maxlen = biglen;
|
pktin.maxlen = biglen;
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
/* allocate enough buffer space for extra block
|
||||||
|
* for MS CryptEncrypt() */
|
||||||
|
pktin.data = (pktin.data == NULL) ?
|
||||||
|
smalloc(biglen+8) : srealloc(pktin.data, biglen+8);
|
||||||
|
#else
|
||||||
pktin.data = (pktin.data == NULL) ?
|
pktin.data = (pktin.data == NULL) ?
|
||||||
smalloc(biglen) : srealloc(pktin.data, biglen);
|
smalloc(biglen) : srealloc(pktin.data, biglen);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = s_read(pktin.data, biglen);
|
ret = s_read(pktin.data, biglen);
|
||||||
@ -162,8 +169,15 @@ static void s_wrpkt_start(int type, int len) {
|
|||||||
pktout.length = len-5;
|
pktout.length = len-5;
|
||||||
if (pktout.maxlen < biglen) {
|
if (pktout.maxlen < biglen) {
|
||||||
pktout.maxlen = biglen;
|
pktout.maxlen = biglen;
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
/* Allocate enough buffer space for extra block
|
||||||
|
* for MS CryptEncrypt() */
|
||||||
|
pktout.data = (pktout.data == NULL ? malloc(biglen+8) :
|
||||||
|
realloc(pktout.data, biglen+8));
|
||||||
|
#else
|
||||||
pktout.data = (pktout.data == NULL ? malloc(biglen+4) :
|
pktout.data = (pktout.data == NULL ? malloc(biglen+4) :
|
||||||
realloc(pktout.data, biglen+4));
|
realloc(pktout.data, biglen+4));
|
||||||
|
#endif
|
||||||
if (!pktout.data)
|
if (!pktout.data)
|
||||||
fatalbox("Out of memory");
|
fatalbox("Out of memory");
|
||||||
}
|
}
|
||||||
@ -488,6 +502,11 @@ char *ssh_init(char *host, int port, char *cmd, char **realhost) {
|
|||||||
int FWport;
|
int FWport;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
if(crypto_startup() == 0)
|
||||||
|
return "Microsoft high encryption pack not installed!";
|
||||||
|
#endif
|
||||||
|
|
||||||
savedhost = malloc(1+strlen(host));
|
savedhost = malloc(1+strlen(host));
|
||||||
if (!savedhost)
|
if (!savedhost)
|
||||||
fatalbox("Out of memory");
|
fatalbox("Out of memory");
|
||||||
|
21
ssh.c
21
ssh.c
@ -152,8 +152,15 @@ static void ssh_gotdata(unsigned char *data, int datalen) {
|
|||||||
pktin.length = len;
|
pktin.length = len;
|
||||||
if (pktin.maxlen < biglen) {
|
if (pktin.maxlen < biglen) {
|
||||||
pktin.maxlen = biglen;
|
pktin.maxlen = biglen;
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
/* Allocate enough buffer space for extra block
|
||||||
|
* for MS CryptEncrypt() */
|
||||||
|
pktin.data = (pktin.data == NULL ? malloc(biglen+8) :
|
||||||
|
realloc(pktin.data, biglen+8));
|
||||||
|
#else
|
||||||
pktin.data = (pktin.data == NULL ? malloc(biglen) :
|
pktin.data = (pktin.data == NULL ? malloc(biglen) :
|
||||||
realloc(pktin.data, biglen));
|
realloc(pktin.data, biglen));
|
||||||
|
#endif
|
||||||
if (!pktin.data)
|
if (!pktin.data)
|
||||||
fatalbox("Out of memory");
|
fatalbox("Out of memory");
|
||||||
}
|
}
|
||||||
@ -199,8 +206,15 @@ static void s_wrpkt_start(int type, int len) {
|
|||||||
pktout.length = len-5;
|
pktout.length = len-5;
|
||||||
if (pktout.maxlen < biglen) {
|
if (pktout.maxlen < biglen) {
|
||||||
pktout.maxlen = biglen;
|
pktout.maxlen = biglen;
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
/* Allocate enough buffer space for extra block
|
||||||
|
* for MS CryptEncrypt() */
|
||||||
|
pktout.data = (pktout.data == NULL ? malloc(biglen+8) :
|
||||||
|
realloc(pktout.data, biglen+8));
|
||||||
|
#else
|
||||||
pktout.data = (pktout.data == NULL ? malloc(biglen+4) :
|
pktout.data = (pktout.data == NULL ? malloc(biglen+4) :
|
||||||
realloc(pktout.data, biglen+4));
|
realloc(pktout.data, biglen+4));
|
||||||
|
#endif
|
||||||
if (!pktout.data)
|
if (!pktout.data)
|
||||||
fatalbox("Out of memory");
|
fatalbox("Out of memory");
|
||||||
}
|
}
|
||||||
@ -685,6 +699,11 @@ static char *ssh_init (HWND hwnd, char *host, int port, char **realhost) {
|
|||||||
char *FWhost;
|
char *FWhost;
|
||||||
int FWport;
|
int FWport;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
if(crypto_startup() == 0)
|
||||||
|
return "Microsoft high encryption pack not installed!";
|
||||||
|
#endif
|
||||||
|
|
||||||
savedhost = malloc(1+strlen(host));
|
savedhost = malloc(1+strlen(host));
|
||||||
if (!savedhost)
|
if (!savedhost)
|
||||||
|
17
ssh.h
17
ssh.h
@ -8,8 +8,13 @@
|
|||||||
struct RSAKey {
|
struct RSAKey {
|
||||||
int bits;
|
int bits;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
unsigned long exponent;
|
||||||
|
unsigned char *modulus;
|
||||||
|
#else
|
||||||
void *modulus;
|
void *modulus;
|
||||||
void *exponent;
|
void *exponent;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int makekey(unsigned char *data, struct RSAKey *result,
|
int makekey(unsigned char *data, struct RSAKey *result,
|
||||||
@ -24,9 +29,13 @@ typedef unsigned int uint32;
|
|||||||
unsigned long crc32(const void *s, size_t len);
|
unsigned long crc32(const void *s, size_t len);
|
||||||
|
|
||||||
struct MD5Context {
|
struct MD5Context {
|
||||||
uint32 buf[4];
|
#ifdef MSCRYPTOAPI
|
||||||
uint32 bits[2];
|
unsigned long hHash;
|
||||||
unsigned char in[64];
|
#else
|
||||||
|
uint32 buf[4];
|
||||||
|
uint32 bits[2];
|
||||||
|
unsigned char in[64];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void MD5Init(struct MD5Context *context);
|
void MD5Init(struct MD5Context *context);
|
||||||
@ -40,7 +49,9 @@ struct ssh_cipher {
|
|||||||
void (*decrypt)(unsigned char *blk, int len);
|
void (*decrypt)(unsigned char *blk, int len);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef MSCRYPTOAPI
|
||||||
void SHATransform(word32 *digest, word32 *data);
|
void SHATransform(word32 *digest, word32 *data);
|
||||||
|
#endif
|
||||||
|
|
||||||
int random_byte(void);
|
int random_byte(void);
|
||||||
void random_add_noise(void *noise, int length);
|
void random_add_noise(void *noise, int length);
|
||||||
|
6
window.c
6
window.c
@ -474,8 +474,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
|
|||||||
DeleteObject(pal);
|
DeleteObject(pal);
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
|
||||||
if (cfg.protocol == PROT_SSH)
|
if (cfg.protocol == PROT_SSH) {
|
||||||
random_save_seed();
|
random_save_seed();
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
crypto_wrapup();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return msg.wParam;
|
return msg.wParam;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user