Hi, Daniel Stenberg wrote: > > Can that date please be pushed two weeks? I'm not sure I can > > find time to finish the code up completely by the 11th. > > Now we're 8 days away from release. I think you need to subit this > work ASAP if you still think you can get it into the release - so > that it gets some time to sink in, get tested and reviewed.
I do think I can get it into the release. I can't post a complete patch today, but maybe tomorrow night. I've attached my current git diff master state for review as well as testing. It has a couple of things which still need to be done, but is already functional. The diff also includes a few unrelated cleanups; a few type issues and not using RSA if the crypto backend does not implement it. > Otherwise I suggest we aim to get that merged for the next release > instead. I would like to get it in now, and look forward to any feedback on the current patch. //Peter
diff --git a/Makefile.axTLS.inc b/Makefile.axTLS.inc new file mode 100644 index 0000000..b63943e --- /dev/null +++ b/Makefile.axTLS.inc @@ -0,0 +1,2 @@ +CRYPTO_CSOURCES = axtls.c +CRYPTO_HHEADERS = axtls.h diff --git a/configure.ac b/configure.ac index d6bdab4..f128494 100644 --- a/configure.ac +++ b/configure.ac @@ -78,6 +78,7 @@ AC_PATH_PROGS(SSHD, [sshd], [], AM_CONDITIONAL(SSHD, test -n "$SSHD") AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL +PKG_PROG_PKG_CONFIG AC_C_BIGENDIAN dnl check for how to do large files @@ -93,6 +94,9 @@ AC_ARG_WITH(libgcrypt, AC_ARG_WITH(wincng, AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]), use_wincng=$withval,use_wincng=auto) +AC_ARG_WITH(axtls, + AC_HELP_STRING([--with-axtls],[Use axTLS for crypto]), + use_axtls=$withval,use_axtls=auto) AC_ARG_WITH(libz, AC_HELP_STRING([--with-libz],[Use zlib for compression]), use_libz=$withval,use_libz=auto) @@ -163,6 +167,17 @@ AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes") AM_CONDITIONAL(OS400QC3, false) +# Look for axTLS +if test "$found_crypto" = "none" && test "$use_axtls" != "no"; then + PKG_CHECK_MODULES([AXTLS], [libaxtls], [ + found_crypto=axTLS + AC_DEFINE(LIBSSH2_AXTLS, 1, [Use axTLS]) + LIBS="$LIBS $AXTLS_LIBS" + ]) +fi +AM_CONDITIONAL(AXTLS, test "$found_crypto" = "axTLS") + + # Check if crypto library was found if test "$found_crypto" = "none"; then AC_MSG_ERROR([No crypto library found! diff --git a/docs/HACKING.CRYPTO b/docs/HACKING.CRYPTO index a8a6a06..6fdcf71 100644 --- a/docs/HACKING.CRYPTO +++ b/docs/HACKING.CRYPTO @@ -316,7 +316,7 @@ _libssh2_bn_ctx Type of multiple precision computation context. May not be empty. if not used, #define as char, for example. -libssh2_bn_ctx _libssh2_bn_ctx_new(void); +_libssh2_bn_ctx _libssh2_bn_ctx_new(void); Returns a new multiple precision computation context. void _libssh2_bn_ctx_free(_libssh2_bn_ctx ctx); @@ -339,7 +339,7 @@ allocates the number. Returns a value of type _libssh2_bn *. void _libssh2_bn_free(_libssh2_bn *bn); Destroys the multiple precision number at bn. -unsigned long _libssh2_bn_bytes(libssh2_bn *bn); +unsigned long _libssh2_bn_bytes(_libssh2_bn *bn); Get the number of bytes needed to store the bits of the multiple precision number at bn. diff --git a/src/Makefile.am b/src/Makefile.am index 1334c55..cbcc812 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,6 +14,9 @@ endif if OS400QC3 include ../Makefile.os400qc3.inc endif +if AXTLS +include ../Makefile.axTLS.inc +endif # Makefile.inc provides the CSOURCES and HHEADERS defines include ../Makefile.inc @@ -60,6 +63,7 @@ VERSION=-version-info 1:1:0 # set age to 0. (c:r:a=0) # +libssh2_la_CFLAGS = $(AXTLS_CFLAGS) libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ -export-symbols-regex '^libssh2_.*' \ - $(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ) + $(LTLIBGCRYPT) $(LTLIBSSL) $(AXTLS_LDFLAGS) $(LTLIBZ) diff --git a/src/axtls.c b/src/axtls.c new file mode 100644 index 0000000..c06429a --- /dev/null +++ b/src/axtls.c @@ -0,0 +1,502 @@ +/* Copyright (c) 2016 Peter Stuge + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#if LIBSSH2_AXTLS + +#include <axTLS/crypto.h> +#include <stdlib.h> + +static BI_CTX *axbictx = NULL; + +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX +#define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + + +/* 1) Crypto library initialization/termination. */ +void libssh2_crypto_init(void) { + axbictx = bi_initialize(); + RNG_initialize(); +} + +void libssh2_crypto_exit(void) { + RNG_terminate(); + bi_terminate(axbictx); +} + + +/* 2) HMAC */ + +static unsigned int hash_blocksize(enum _libssh2_axtls_hmac_type type) { + switch (type) { + case HMAC_MD5: + case HMAC_SHA1: + case HMAC_SHA256: + return 64; + case HMAC_SHA512: + return 128; + } + return 0; +} + +void libssh2_axtls_hmac_ctx_init(libssh2_hmac_ctx *ctx, enum _libssh2_axtls_hmac_type type, const void *key, int keylen) { + size_t i, klen = keylen; + const unsigned char *k = key; + + ctx->type = type; + ctx->k_size = hash_blocksize(type); + + for (i = 0; i < ctx->k_size; i++) + ctx->k[i] = (i < klen ? k[i] : 0) ^ 0x36; + + switch (ctx->type) { + case HMAC_MD5: + ctx->h.md5 = &ctx->hctx.md5; + MD5_Init(ctx->h.md5); + MD5_Update(ctx->h.md5, ctx->k, ctx->k_size); + break; + + case HMAC_SHA1: + ctx->h.sha1 = &ctx->hctx.sha1; + SHA1_Init(ctx->h.sha1); + SHA1_Update(ctx->h.sha1, ctx->k, ctx->k_size); + break; + + case HMAC_SHA256: + ctx->h.sha256 = &ctx->hctx.sha256; + SHA256_Init(ctx->h.sha256); + SHA256_Update(ctx->h.sha256, ctx->k, ctx->k_size); + break; + + case HMAC_SHA512: + ctx->h.sha512 = &ctx->hctx.sha512; + SHA512_Init(ctx->h.sha512); + SHA512_Update(ctx->h.sha512, ctx->k, ctx->k_size); + break; + } + + for (i = 0; i < ctx->k_size; i++) + ctx->k[i] = (i < klen ? k[i] : 0) ^ 0x5c; +} + +void libssh2_axtls_hmac_update(libssh2_hmac_ctx *ctx, const unsigned char *data, int datalen) { + switch (ctx->type) { + case HMAC_MD5: MD5_Update(ctx->h.md5, data, datalen); return; + case HMAC_SHA1: SHA1_Update(ctx->h.sha1, data, datalen); return; + case HMAC_SHA256: SHA256_Update(ctx->h.sha256, data, datalen); return; + case HMAC_SHA512: SHA512_Update(ctx->h.sha512, data, datalen); return; + } +} + +void libssh2_axtls_hmac_final(libssh2_hmac_ctx *ctx, unsigned char *output) { + union { + MD5_CTX md5; + SHA1_CTX sha1; + SHA256_CTX sha256; + SHA512_CTX sha512; + } hctx; + MD5_CTX *md5 = &hctx.md5; + SHA1_CTX *sha1 = &hctx.sha1; + SHA256_CTX *sha256 = &hctx.sha256; + SHA512_CTX *sha512 = &hctx.sha512; + + switch (ctx->type) { + case HMAC_MD5: + MD5_Final(output, ctx->h.md5); + MD5_Init(md5); + MD5_Update(md5, ctx->k, ctx->k_size); + MD5_Update(md5, output, MD5_SIZE); + MD5_Final(output, md5); + memset(md5, 0, sizeof hctx.md5); + break; + + case HMAC_SHA1: + SHA1_Final(output, ctx->h.sha1); + SHA1_Init(sha1); + SHA1_Update(sha1, ctx->k, ctx->k_size); + SHA1_Update(sha1, output, SHA1_SIZE); + SHA1_Final(output, sha1); + memset(sha1, 0, sizeof hctx.sha1); + break; + + case HMAC_SHA256: + SHA256_Final(output, ctx->h.sha256); + SHA256_Init(sha256); + SHA256_Update(sha256, ctx->k, ctx->k_size); + SHA256_Update(sha256, output, SHA256_SIZE); + SHA256_Final(output, sha256); + memset(sha256, 0, sizeof hctx.sha256); + break; + + case HMAC_SHA512: + SHA512_Final(output, ctx->h.sha512); + SHA512_Init(sha512); + SHA512_Update(sha512, ctx->k, ctx->k_size); + SHA512_Update(sha512, output, SHA512_SIZE); + SHA512_Final(output, sha512); + memset(sha512, 0, sizeof hctx.sha512); + break; + } +} + +void libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx) { + memset(ctx->k, 0, sizeof ctx->k); + + switch (ctx->type) { + case HMAC_MD5: + memset(ctx->h.md5, 0, sizeof ctx->hctx.md5); + break; + + case HMAC_SHA1: + memset(ctx->h.sha1, 0, sizeof ctx->hctx.sha1); + break; + + case HMAC_SHA256: + memset(ctx->h.sha256, 0, sizeof ctx->hctx.sha256); + break; + + case HMAC_SHA512: + memset(ctx->h.sha512, 0, sizeof ctx->hctx.sha512); + break; + } +} + + +/* 3.1) SHA-1 */ + +int libssh2_sha1_init(libssh2_sha1_ctx *x) { + SHA1_Init(x); + return 1; +} + + +/* 3.2) SHA-256 */ + +int libssh2_sha256_init(libssh2_sha256_ctx *x) { + SHA256_Init(x); + return 1; +} + +int libssh2_sha256(const unsigned char *message, unsigned long len, unsigned char *output) { + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, message, len); + SHA256_Final(output, &ctx); + return 0; +} + + +/* 3.4) MD5 */ + +int libssh2_md5_init(libssh2_md5_ctx *x) { + MD5_Init(x); + return 1; +} + + +/* 4) Bidirectional Key ciphers. */ + +static AES_MODE aes_mode_from_type(_libssh2_cipher_type(algo)) { + switch (algo) { + case AES_128_CBC: return AES_MODE_128; + case AES_256_CBC: return AES_MODE_256; + } +} + +int _libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { + switch (algo) { + case AES_192_CBC: + /* not implemented in axTLS */ + return -1; + + case AES_128_CBC: + case AES_256_CBC: + AES_set_key(&h->aes, secret, iv, aes_mode_from_type(algo)); + if (!encrypt) + AES_convert_key(&h->aes); + break; + + case RC4: + RC4_setup(&h->rc4, secret, 16); + break; + } + + return 0; +} + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize) { + switch (algo) { + case AES_192_CBC: + /* not implemented in axTLS */ + return -1; + + case AES_128_CBC: + case AES_256_CBC: + if (encrypt) + AES_cbc_encrypt(&ctx->aes, block, block, blocksize); + else + AES_cbc_decrypt(&ctx->aes, block, block, blocksize); + break; + + case RC4: + RC4_crypt(&ctx->rc4, block, block, blocksize); + break; + } + + return 0; +} + +void _libssh2_cipher_dtor(_libssh2_cipher_ctx *ctx) { + memset(&ctx->aes, 0, sizeof ctx->aes); + memset(&ctx->rc4, 0, sizeof ctx->rc4); +} + + +/* 5) Big numbers. */ + +_libssh2_bn_ctx *_libssh2_bn_ctx_new(void) { + return axbictx; +} + +_libssh2_bn *_libssh2_bn_init(void) { + return int_to_bi(axbictx, 0); +} + +_libssh2_bn *_libssh2_bn_init_from_bin(void) { + return NULL; +} + +void _libssh2_bn_free(_libssh2_bn *bn) { + if (bn) + bi_free(axbictx, bn); +} + +unsigned long _libssh2_bn_bytes(_libssh2_bn *bn) { + unsigned long n = COMP_BYTE_SIZE * bn->size; + comp mask = 0xff; + + for (mask <<= COMP_BIT_SIZE-8; mask; mask >>= 8, n--) + if (bn->comps[bn->size - 1] & mask) + break; + + return n; +} + +unsigned long _libssh2_bn_bits(_libssh2_bn *bn) { + unsigned long n = COMP_BIT_SIZE * bn->size; + comp mask = 1; + + for (mask <<= COMP_BIT_SIZE-1; mask; mask >>= 1, n--) + if (bn->comps[bn->size - 1] & mask) + break; + + return n; +} + +_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_ulong(_libssh2_bn *old, unsigned long val) { + _libssh2_bn *ret = int_to_bi(axbictx, val); + if (old) + bi_free(axbictx, old); + return ret; +} + +_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_bin(_libssh2_bn *old, int len, const unsigned char *val) { + _libssh2_bn *ret = bi_import(axbictx, val, len); + if (old) + bi_free(axbictx, old); + return ret; +} + +int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val) { + unsigned char *b, *buf; + int ret = _libssh2_bn_bytes(bn); + unsigned long n = COMP_BYTE_SIZE * bn->size; + + b = buf = malloc(n); + if (!buf) + return -1; + + bi_copy(bn); + bi_export(axbictx, bn, buf, n); + + while (!*b) + b++; + + memcpy(val, b, ret); + free(buf); + + return ret; +} + + +/* TODO +Generates a cryptographically strong pseudo-random number of bits in +length and stores it in bn. If top is -1, the most significant bit of the +random number can be zero. If top is 0, it is set to 1, and if top is 1, the +two most significant bits of the number will be set to 1, so that the product +of two such random numbers will always have 2*bits length. If bottom is true, +the number will be odd. +*/ +_libssh2_bn *_libssh2_bn_free_and_new_rand(_libssh2_bn *bn, int bits, int top, int bottom) { + int bytes = bits+7/8; + unsigned char *buf = malloc(bytes); + _libssh2_bn *ret; + + bi_free(axbictx, bn); + get_random(bytes, buf); + ret = bi_import(axbictx, buf, bytes); + free(buf); + + /* TODO: bits top bottom */ + + return ret; +} + + +/* r=a^p % m, May use the given context. */ +_libssh2_bn *_libssh2_axtls_free_and_new_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m, _libssh2_bn_ctx *ctx) { + bi_free(axbictx, r); + bi_copy(a); + bi_copy(p); + bi_copy(m); + return bi_mod_power2(ctx, a, m, p); +} + + +/* 6) Private key algorithms. */ + +int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { + /* TODO */ + return -1; +} + +int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { + /* TODO */ + return -1; +} + + +/* 6.1) RSA */ + +int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, unsigned long elen, + const unsigned char *ndata, unsigned long nlen, + const unsigned char *ddata, unsigned long dlen, + const unsigned char *pdata, unsigned long plen, + const unsigned char *qdata, unsigned long qlen, + const unsigned char *e1data, unsigned long e1len, + const unsigned char *e2data, unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) { + *rsa = NULL; + RSA_pub_key_new(rsa, ndata, nlen, edata, elen); + return 0; +} + +int _libssh2_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, unsigned const char *passphrase) { + _libssh2_init_if_needed(); + /* TODO */ + return -1; +} + +int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *data, size_t data_len, unsigned const char *passphrase) { + _libssh2_init_if_needed(); + /* TODO */ + return -1; +} + +#define OID_SHA1_LEN 15 +static const unsigned char oid_sha1[OID_SHA1_LEN] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, + 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 +}; + +int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len) { + int ret = -1; + SHA1_CTX h; + bigint *s, *v; + unsigned long vlen; + unsigned char *p, *ver, hash[SHA1_SIZE]; + + s = bi_import(axbictx, sig, sig_len); + v = RSA_public(rsa, s); + + vlen = _libssh2_bn_bytes(v); + p = ver = malloc(vlen); + if (!ver) + return -1; + + bi_export(axbictx, v, ver, vlen); + + if (ver[0] != 0x01) + goto done; + + if (vlen < 1 + 1 + sizeof oid_sha1 + sizeof hash) + goto done; + + p = ver + (vlen - sizeof hash - sizeof oid_sha1); + if (memcmp(p, oid_sha1, sizeof oid_sha1)) + goto done; + + p += sizeof oid_sha1; + + SHA1_Init(&h); + SHA1_Update(&h, m, m_len); + SHA1_Final(hash, &h); + + if (memcmp(p, hash, sizeof hash)) + goto done; + + ret = 0; + +done: + memset(ver, 0, vlen); + memset(&h, 0, sizeof h); + free(ver); + return ret; +} + +int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { + /* TODO */ + return -1; +} + +#endif /* LIBSSH2_AXTLS */ diff --git a/src/axtls.h b/src/axtls.h new file mode 100644 index 0000000..27bcfaa --- /dev/null +++ b/src/axtls.h @@ -0,0 +1,227 @@ +/* Copyright (c) 2016 Peter Stuge + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef _AXTLS_H_ +#define _AXTLS_H_ + +#include <axTLS/crypto.h> + + +/* 1) Crypto library initialization/termination. */ +void libssh2_crypto_init(void); +void libssh2_crypto_exit(void); + + +/* 2) HMAC */ +enum _libssh2_axtls_hmac_type { + HMAC_MD5 = 0, + HMAC_SHA1, + HMAC_SHA256, + HMAC_SHA512 +}; + +typedef struct _libssh2_axtls_hmac_ctx { + enum _libssh2_axtls_hmac_type type; + + unsigned char k[128]; + unsigned char k_size; + + union { + MD5_CTX md5; + SHA1_CTX sha1; + SHA256_CTX sha256; + SHA512_CTX sha512; + } hctx; + union { + MD5_CTX *md5; + SHA1_CTX *sha1; + SHA256_CTX *sha256; + SHA512_CTX *sha512; + } h; +} libssh2_hmac_ctx; + +void libssh2_axtls_hmac_ctx_init(libssh2_hmac_ctx *ctx, enum _libssh2_axtls_hmac_type type, const void *key, int keylen); +void libssh2_axtls_hmac_update(libssh2_hmac_ctx *ctx, const unsigned char *data, int datalen); +void libssh2_axtls_hmac_final(libssh2_hmac_ctx *ctx, unsigned char *output); + +#define libssh2_hmac_ctx_init(x) do { } while (0) +#define libssh2_hmac_update(ctx, data, datalen) libssh2_axtls_hmac_update(&(ctx), data, datalen) +#define libssh2_hmac_final(ctx, output) libssh2_axtls_hmac_final(&(ctx), output) + +void libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx); + + +/* 3.1) SHA-1 */ +#define SHA_DIGEST_LENGTH SHA1_SIZE +typedef SHA1_CTX libssh2_sha1_ctx; +int libssh2_sha1_init(libssh2_sha1_ctx *x); +#define libssh2_sha1_update(ctx, data, len) SHA1_Update(&ctx, data, len) +#define libssh2_sha1_final(ctx, output) SHA1_Final(output, &ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_SHA1, key, keylen) + + +/* 3.2) SHA-256 */ +#define SHA256_DIGEST_LENGTH SHA256_SIZE +typedef SHA256_CTX libssh2_sha256_ctx; +int libssh2_sha256_init(libssh2_sha256_ctx *x); +#define libssh2_sha256_update(ctx, data, len) SHA256_Update(&ctx, data, len) +#define libssh2_sha256_final(ctx, output) SHA256_Final(output, &ctx) +int libssh2_sha256(const unsigned char *message, unsigned long len, unsigned char *output); + +#define LIBSSH2_HMAC_SHA256 1 +#define libssh2_hmac_sha256_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_SHA256, key, keylen) + + +/* 3.3) SHA-512 (HMAC-SHA512) */ +#define LIBSSH2_HMAC_SHA512 1 +#define libssh2_hmac_sha512_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_SHA512, key, keylen) + + +/* 3.4) MD5 */ +#define LIBSSH2_MD5 1 +#define MD5_DIGEST_LENGTH MD5_SIZE +typedef MD5_CTX libssh2_md5_ctx; +int libssh2_md5_init(libssh2_md5_ctx *x); +#define libssh2_md5_update(ctx, data, len) MD5_Update(&ctx, data, len) +#define libssh2_md5_final(ctx, output) MD5_Final(output, &ctx) +#define libssh2_hmac_md5_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_MD5, key, keylen) + + +/* 3.5) RIPEMD-160 */ +#define LIBSSH2_HMAC_RIPEMD 0 + + +/* 4) Bidirectional Key ciphers. */ + +enum _libssh2_axtls_cipher_type { + AES_128_CBC = 0, + AES_192_CBC, + AES_256_CBC, + RC4 +}; + +typedef union _libssh2_axtls_cipher_ctx { + AES_CTX aes; + RC4_CTX rc4; +} _libssh2_cipher_ctx; + +#define _libssh2_cipher_type(name) enum _libssh2_axtls_cipher_type name + +int _libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt); +int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize); +void _libssh2_cipher_dtor(_libssh2_cipher_ctx *ctx); + + + +/* 4.1) AES +4.1.1) AES in CBC block mode. */ +#define LIBSSH2_AES 1 +#define _libssh2_cipher_aes128 AES_128_CBC +#define _libssh2_cipher_aes192 AES_192_CBC +#define _libssh2_cipher_aes256 AES_256_CBC + + +/* 4.1.2) AES in CTR block mode. */ +#define LIBSSH2_AES_CTR 0 + + +/* 4.2) Blowfish in CBC block mode. */ +#define LIBSSH2_BLOWFISH 0 + + +/* 4.3) RC4. */ +#define LIBSSH2_RC4 1 +#define _libssh2_cipher_arcfour RC4 + + +/* 4.4) CAST5 in CBC block mode. */ +#define LIBSSH2_CAST 0 + + +/* 4.5) Tripple DES in CBC block mode. */ +#define LIBSSH2_3DES 0 + + +/* 5) Big numbers. */ +typedef BI_CTX _libssh2_bn_ctx; + +_libssh2_bn_ctx *_libssh2_bn_ctx_new(void); +#define _libssh2_bn_ctx_free(ctx) do { } while (0) + +typedef bigint _libssh2_bn; + +_libssh2_bn *_libssh2_bn_init(void); +_libssh2_bn *_libssh2_bn_init_from_bin(void); +void _libssh2_bn_free(_libssh2_bn *bn); +unsigned long _libssh2_bn_bytes(_libssh2_bn *bn); +unsigned long _libssh2_bn_bits(_libssh2_bn *bn); + +_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_ulong(_libssh2_bn *old, unsigned long val); +/* this is supposed to return 1, but nobody checks it */ +#define _libssh2_bn_set_word(bn, val) bn = _libssh2_axtls_bn_free_and_new_from_ulong(bn, val) + +_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_bin(_libssh2_bn *old, int len, const unsigned char *val); +/* this is supposed to return NULL on error, but nobody checks it */ +#define _libssh2_bn_from_bin(bn, len, val) bn = _libssh2_axtls_bn_free_and_new_from_bin(bn, len, val) + +int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val); + +_libssh2_bn *_libssh2_bn_free_and_new_rand(_libssh2_bn *bn, int bits, int top, int bottom); +#define _libssh2_bn_rand(bn, bits, top, bottom) bn = _libssh2_bn_free_and_new_rand(bn, bits, top, bottom) + +_libssh2_bn *_libssh2_axtls_free_and_new_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m, _libssh2_bn_ctx *ctx); +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) r = _libssh2_axtls_free_and_new_bn_mod_exp(r, a, p, m, ctx) + + +/* 6.1) RSA */ +#define LIBSSH2_RSA 1 + +typedef RSA_CTX libssh2_rsa_ctx; + +#define _libssh2_rsa_free RSA_free + + +/* 6.2) DSA */ +#define LIBSSH2_DSA 0 + + +/* 7) Miscellaneous */ + +#define libssh2_prepare_iovec(vector, len) do { } while (0) +#define _libssh2_random(buf, len) get_random(len, buf) + + +#endif /* _AXTLS_H_ */ diff --git a/src/crypto.h b/src/crypto.h index caad19f..452505a 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -54,6 +54,11 @@ #include "os400qc3.h" #endif +#ifdef LIBSSH2_AXTLS +#include "axtls.h" +#endif + +#if LIBSSH2_RSA int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, const unsigned char *edata, unsigned long elen, @@ -88,6 +93,7 @@ int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); +#endif #if LIBSSH2_DSA int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa, diff --git a/src/global.c b/src/global.c index dc45e70..353ffce 100644 --- a/src/global.c +++ b/src/global.c @@ -46,7 +46,9 @@ libssh2_init(int flags) { if (_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) { libssh2_crypto_init(); +#if LIBSSH2_AES_CTR _libssh2_init_aes_ctr(); +#endif } _libssh2_initialized++; diff --git a/src/kex.c b/src/kex.c index 65b722f..fcf6c41 100644 --- a/src/kex.c +++ b/src/kex.c @@ -357,7 +357,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, libssh2_sha1_update(exchange_hash_ctx, exchange_state->h_sig_comp, 4); libssh2_sha1_update(exchange_hash_ctx, - (char *) session->local.banner, + session->local.banner, strlen((char *) session->local.banner) - 2); } else { _libssh2_htonu32(exchange_state->h_sig_comp, @@ -365,7 +365,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, libssh2_sha1_update(exchange_hash_ctx, exchange_state->h_sig_comp, 4); libssh2_sha1_update(exchange_hash_ctx, - LIBSSH2_SSH_DEFAULT_BANNER, + (const unsigned char *)LIBSSH2_SSH_DEFAULT_BANNER, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); } @@ -517,14 +517,14 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->local.crypt-> - iv_len, "A"); + iv_len, (unsigned char *)"A"); if (!iv) { ret = -1; goto clean_exit; } LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->local.crypt-> - secret_len, "C"); + secret_len, (unsigned char *)"C"); if (!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; @@ -564,14 +564,14 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->remote.crypt-> - iv_len, "B"); + iv_len, (unsigned char *)"B"); if (!iv) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->remote.crypt-> - secret_len, "D"); + secret_len, (unsigned char *)"D"); if (!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; @@ -609,7 +609,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->local.mac-> - key_len, "E"); + key_len, (unsigned char *)"E"); if (!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; @@ -635,7 +635,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->remote.mac-> - key_len, "F"); + key_len, (unsigned char *)"F"); if (!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; @@ -977,7 +977,7 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, libssh2_sha256_update(exchange_hash_ctx, exchange_state->h_sig_comp, 4); libssh2_sha256_update(exchange_hash_ctx, - (char *) session->local.banner, + session->local.banner, strlen((char *) session->local.banner) - 2); } else { _libssh2_htonu32(exchange_state->h_sig_comp, @@ -985,7 +985,7 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, libssh2_sha256_update(exchange_hash_ctx, exchange_state->h_sig_comp, 4); libssh2_sha256_update(exchange_hash_ctx, - LIBSSH2_SSH_DEFAULT_BANNER, + (unsigned char *)LIBSSH2_SSH_DEFAULT_BANNER, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); } @@ -1139,14 +1139,14 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv, session->local.crypt-> - iv_len, "A"); + iv_len, (unsigned char *)"A"); if (!iv) { ret = -1; goto clean_exit; } LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret, session->local.crypt-> - secret_len, "C"); + secret_len, (unsigned char *)"C"); if (!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; @@ -1186,14 +1186,14 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv, session->remote.crypt-> - iv_len, "B"); + iv_len, (unsigned char *)"B"); if (!iv) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret, session->remote.crypt-> - secret_len, "D"); + secret_len, (unsigned char *)"D"); if (!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; @@ -1231,7 +1231,7 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key, session->local.mac-> - key_len, "E"); + key_len, (unsigned char *)"E"); if (!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; @@ -1256,8 +1256,8 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, int free_key = 0; LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key, - session->remote.mac-> - key_len, "F"); + session->remote.mac->key_len, + (unsigned char *)"F"); if (!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; diff --git a/src/userauth.c b/src/userauth.c index cdfa25e..51c6afb 100644 --- a/src/userauth.c +++ b/src/userauth.c @@ -786,6 +786,10 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session, { int rc; +#if !LIBSSH2_RSA + return -1; +#endif + if (session->userauth_host_state == libssh2_NB_state_idle) { const LIBSSH2_HOSTKEY_METHOD *privkeyobj; unsigned char *pubkeydata, *sig = NULL; @@ -1378,6 +1382,10 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session, void *abstract = &privkey_file; int rc; +#if !LIBSSH2_RSA + return -1; +#endif + privkey_file.filename = privatekeydata; privkey_file.passphrase = passphrase; @@ -1435,6 +1443,10 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session, void *abstract = &privkey_file; int rc; +#if !LIBSSH2_RSA + return -1; +#endif + privkey_file.filename = privatekey; privkey_file.passphrase = passphrase;
_______________________________________________ libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel