summaryrefslogtreecommitdiff
path: root/libs/libssh2/src/hostkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libssh2/src/hostkey.c')
-rw-r--r--libs/libssh2/src/hostkey.c453
1 files changed, 372 insertions, 81 deletions
diff --git a/libs/libssh2/src/hostkey.c b/libs/libssh2/src/hostkey.c
index a8bd42b7a0..56eee369f5 100644
--- a/libs/libssh2/src/hostkey.c
+++ b/libs/libssh2/src/hostkey.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
- * Copyright (c) 2009-2019 by Daniel Stenberg
+/* Copyright (C) Sara Golemon <sarag@libssh2.org>
+ * Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -34,10 +34,11 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
-#include "misc.h"
/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
@@ -64,8 +65,8 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
- unsigned char *e, *n;
- size_t e_len, n_len;
+ unsigned char *e, *n, *type;
+ size_t e_len, n_len, type_len;
struct string_buf buf;
if(*abstract) {
@@ -74,8 +75,8 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
}
if(hostkey_data_len < 19) {
- _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
- "host key length too short");
+ _libssh2_debug((session, LIBSSH2_TRACE_ERROR,
+ "host key length too short"));
return -1;
}
@@ -83,8 +84,31 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
- if(_libssh2_match_string(&buf, "ssh-rsa"))
+ if(_libssh2_get_string(&buf, &type, &type_len)) {
+ return -1;
+ }
+
+ /* we accept one of 3 header types */
+#if LIBSSH2_RSA_SHA1
+ if(type_len == 7 && strncmp("ssh-rsa", (char *)type, 7) == 0) {
+ /* ssh-rsa */
+ }
+ else
+#endif
+#if LIBSSH2_RSA_SHA2
+ if(type_len == 12 && strncmp("rsa-sha2-256", (char *)type, 12) == 0) {
+ /* rsa-sha2-256 */
+ }
+ else if(type_len == 12 && strncmp("rsa-sha2-512", (char *)type, 12) == 0) {
+ /* rsa-sha2-512 */
+ }
+ else
+#endif
+ {
+ _libssh2_debug((session, LIBSSH2_TRACE_ERROR,
+ "unexpected rsa type: %.*s", type_len, type));
return -1;
+ }
if(_libssh2_get_string(&buf, &e, &e_len))
return -1;
@@ -92,8 +116,14 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&buf, &n, &n_len))
return -1;
- if(_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
- NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) {
+ if(!_libssh2_eob(&buf))
+ return -1;
+
+ if(_libssh2_rsa_new(&rsactx,
+ e, (unsigned long)e_len,
+ n, (unsigned long)n_len,
+ NULL, 0, NULL, 0, NULL, 0,
+ NULL, 0, NULL, 0, NULL, 0)) {
return -1;
}
@@ -163,6 +193,7 @@ hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
return 0;
}
+#if LIBSSH2_RSA_SHA1
/*
* hostkey_method_ssh_rsa_sign
*
@@ -176,7 +207,7 @@ hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
size_t m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
- (void) session;
+ (void)session;
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
if(sig_len < 15)
@@ -211,7 +242,7 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx;
- libssh2_sha1_init(&ctx);
+ (void)libssh2_sha1_init(&ctx);
for(i = 0; i < veccount; i++) {
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
}
@@ -226,6 +257,151 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
return 0;
#endif
}
+#endif
+
+/*
+ * hostkey_method_ssh_rsa_sha2_256_sig_verify
+ *
+ * Verify signature created by remote
+ */
+#if LIBSSH2_RSA_SHA2
+
+static int
+hostkey_method_ssh_rsa_sha2_256_sig_verify(LIBSSH2_SESSION * session,
+ const unsigned char *sig,
+ size_t sig_len,
+ const unsigned char *m,
+ size_t m_len, void **abstract)
+{
+ libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
+ (void)session;
+
+ /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-256"} +
+ signature_len(4) */
+ if(sig_len < 20)
+ return -1;
+
+ sig += 20;
+ sig_len -= 20;
+ return _libssh2_rsa_sha2_verify(rsactx, SHA256_DIGEST_LENGTH, sig, sig_len,
+ m, m_len);
+}
+
+/*
+ * hostkey_method_ssh_rsa_sha2_256_signv
+ *
+ * Construct a signature from an array of vectors
+ */
+
+static int
+hostkey_method_ssh_rsa_sha2_256_signv(LIBSSH2_SESSION * session,
+ unsigned char **signature,
+ size_t *signature_len,
+ int veccount,
+ const struct iovec datavec[],
+ void **abstract)
+{
+ libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
+
+#ifdef _libssh2_rsa_sha2_256_signv
+ return _libssh2_rsa_sha2_256_signv(session, signature, signature_len,
+ veccount, datavec, rsactx);
+#else
+ int ret;
+ int i;
+ unsigned char hash[SHA256_DIGEST_LENGTH];
+ libssh2_sha256_ctx ctx;
+
+ if(!libssh2_sha256_init(&ctx)) {
+ return -1;
+ }
+ for(i = 0; i < veccount; i++) {
+ libssh2_sha256_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
+ }
+ libssh2_sha256_final(ctx, hash);
+
+ ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA256_DIGEST_LENGTH,
+ signature, signature_len);
+ if(ret) {
+ return -1;
+ }
+
+ return 0;
+#endif
+}
+
+/*
+ * hostkey_method_ssh_rsa_sha2_512_sig_verify
+ *
+ * Verify signature created by remote
+ */
+
+static int
+hostkey_method_ssh_rsa_sha2_512_sig_verify(LIBSSH2_SESSION * session,
+ const unsigned char *sig,
+ size_t sig_len,
+ const unsigned char *m,
+ size_t m_len, void **abstract)
+{
+ libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
+ (void)session;
+
+ /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-512"} +
+ signature_len(4) */
+ if(sig_len < 20)
+ return -1;
+
+ sig += 20;
+ sig_len -= 20;
+ return _libssh2_rsa_sha2_verify(rsactx, SHA512_DIGEST_LENGTH, sig,
+ sig_len, m, m_len);
+}
+
+
+/*
+ * hostkey_method_ssh_rsa_sha2_512_signv
+ *
+ * Construct a signature from an array of vectors
+ */
+static int
+hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session,
+ unsigned char **signature,
+ size_t *signature_len,
+ int veccount,
+ const struct iovec datavec[],
+ void **abstract)
+{
+ libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
+
+#ifdef _libssh2_rsa_sha2_512_signv
+ return _libssh2_rsa_sha2_512_signv(session, signature, signature_len,
+ veccount, datavec, rsactx);
+#else
+ int ret;
+ int i;
+ unsigned char hash[SHA512_DIGEST_LENGTH];
+ libssh2_sha512_ctx ctx;
+
+ if(!libssh2_sha512_init(&ctx)) {
+ return -1;
+ }
+ for(i = 0; i < veccount; i++) {
+ libssh2_sha512_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
+ }
+ libssh2_sha512_final(ctx, hash);
+
+ ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA512_DIGEST_LENGTH,
+ signature, signature_len);
+ if(ret) {
+ return -1;
+ }
+
+ return 0;
+#endif
+}
+
+#endif /* LIBSSH2_RSA_SHA2 */
+
/*
* hostkey_method_ssh_rsa_dtor
@@ -236,7 +412,7 @@ static int
hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
- (void) session;
+ (void)session;
_libssh2_rsa_free(rsactx);
@@ -245,13 +421,11 @@ hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
-#ifdef OPENSSL_NO_MD5
-#define MD5_DIGEST_LENGTH 16
-#endif
+#if LIBSSH2_RSA_SHA1
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
"ssh-rsa",
- MD5_DIGEST_LENGTH,
+ SHA_DIGEST_LENGTH,
hostkey_method_ssh_rsa_init,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
@@ -260,6 +434,53 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
+
+#endif /* LIBSSH2_RSA_SHA1 */
+
+#if LIBSSH2_RSA_SHA2
+
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_256 = {
+ "rsa-sha2-256",
+ SHA256_DIGEST_LENGTH,
+ hostkey_method_ssh_rsa_init,
+ hostkey_method_ssh_rsa_initPEM,
+ hostkey_method_ssh_rsa_initPEMFromMemory,
+ hostkey_method_ssh_rsa_sha2_256_sig_verify,
+ hostkey_method_ssh_rsa_sha2_256_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_rsa_dtor,
+};
+
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_512 = {
+ "rsa-sha2-512",
+ SHA512_DIGEST_LENGTH,
+ hostkey_method_ssh_rsa_init,
+ hostkey_method_ssh_rsa_initPEM,
+ hostkey_method_ssh_rsa_initPEMFromMemory,
+ hostkey_method_ssh_rsa_sha2_512_sig_verify,
+ hostkey_method_ssh_rsa_sha2_512_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_rsa_dtor,
+};
+
+#endif /* LIBSSH2_RSA_SHA2 */
+
+#if LIBSSH2_RSA_SHA1
+
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_cert = {
+ "ssh-rsa-cert-v01@openssh.com",
+ SHA_DIGEST_LENGTH,
+ NULL,
+ hostkey_method_ssh_rsa_initPEM,
+ hostkey_method_ssh_rsa_initPEMFromMemory,
+ NULL,
+ hostkey_method_ssh_rsa_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_rsa_dtor,
+};
+
+#endif /* LIBSSH2_RSA_SHA1 */
+
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
@@ -292,8 +513,8 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
}
if(hostkey_data_len < 27) {
- _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
- "host key length too short");
+ _libssh2_debug((session, LIBSSH2_TRACE_ERROR,
+ "host key length too short"));
return -1;
}
@@ -305,7 +526,7 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
return -1;
if(_libssh2_get_string(&buf, &p, &p_len))
- return -1;
+ return -1;
if(_libssh2_get_string(&buf, &q, &q_len))
return -1;
@@ -316,8 +537,15 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&buf, &y, &y_len))
return -1;
- if(_libssh2_dsa_new(&dsactx, p, p_len, q, q_len,
- g, g_len, y, y_len, NULL, 0)) {
+ if(!_libssh2_eob(&buf))
+ return -1;
+
+ if(_libssh2_dsa_new(&dsactx,
+ p, (unsigned long)p_len,
+ q, (unsigned long)q_len,
+ g, (unsigned long)g_len,
+ y, (unsigned long)y_len,
+ NULL, 0)) {
return -1;
}
@@ -438,7 +666,7 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
*signature_len = 2 * SHA_DIGEST_LENGTH;
- libssh2_sha1_init(&ctx);
+ (void)libssh2_sha1_init(&ctx);
for(i = 0; i < veccount; i++) {
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
}
@@ -461,7 +689,7 @@ static int
hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
- (void) session;
+ (void)session;
_libssh2_dsa_free(dsactx);
@@ -472,7 +700,7 @@ hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = {
"ssh-dss",
- MD5_DIGEST_LENGTH,
+ SHA_DIGEST_LENGTH,
hostkey_method_ssh_dss_init,
hostkey_method_ssh_dss_initPEM,
hostkey_method_ssh_dss_initPEMFromMemory,
@@ -500,9 +728,9 @@ hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
- const unsigned char *hostkey_data,
- size_t hostkey_data_len,
- void **abstract)
+ const unsigned char *hostkey_data,
+ size_t hostkey_data_len,
+ void **abstract)
{
libssh2_ecdsa_ctx *ecdsactx = NULL;
unsigned char *type_str, *domain, *public_key;
@@ -510,14 +738,14 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
libssh2_curve_type type;
struct string_buf buf;
- if(abstract != NULL && *abstract) {
+ if(abstract && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
if(hostkey_data_len < 39) {
- _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
- "host key length too short");
+ _libssh2_debug((session, LIBSSH2_TRACE_ERROR,
+ "host key length too short"));
return -1;
}
@@ -561,11 +789,14 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&buf, &public_key, &key_len))
return -1;
+ if(!_libssh2_eob(&buf))
+ return -1;
+
if(_libssh2_ecdsa_curve_name_with_octal_new(&ecdsactx, public_key,
key_len, type))
return -1;
- if(abstract != NULL)
+ if(abstract)
*abstract = ecdsactx;
return 0;
@@ -578,14 +809,14 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
- const char *privkeyfile,
- unsigned const char *passphrase,
- void **abstract)
+ const char *privkeyfile,
+ unsigned const char *passphrase,
+ void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = NULL;
int ret;
- if(abstract != NULL && *abstract) {
+ if(abstract && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
@@ -593,7 +824,7 @@ hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
ret = _libssh2_ecdsa_new_private(&ec_ctx, session,
privkeyfile, passphrase);
- if(abstract != NULL)
+ if(abstract)
*abstract = ec_ctx;
return ret;
@@ -606,15 +837,15 @@ hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session,
- const char *privkeyfiledata,
- size_t privkeyfiledata_len,
- unsigned const char *passphrase,
- void **abstract)
+ const char *privkeyfiledata,
+ size_t privkeyfiledata_len,
+ unsigned const char *passphrase,
+ void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = NULL;
int ret;
- if(abstract != NULL && *abstract) {
+ if(abstract && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
@@ -627,7 +858,7 @@ hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session,
return -1;
}
- if(abstract != NULL)
+ if(abstract)
*abstract = ec_ctx;
return 0;
@@ -647,11 +878,11 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
{
unsigned char *r, *s, *name;
size_t r_len, s_len, name_len;
- unsigned int len;
+ uint32_t len;
struct string_buf buf;
libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract);
- (void) session;
+ (void)session;
if(sig_len < 35)
return -1;
@@ -662,14 +893,14 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = sig_len;
- if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19)
+ if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19)
return -1;
if(_libssh2_get_u32(&buf, &len) != 0 || len < 8)
return -1;
if(_libssh2_get_string(&buf, &r, &r_len))
- return -1;
+ return -1;
if(_libssh2_get_string(&buf, &s, &s_len))
return -1;
@@ -679,11 +910,11 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \
- { \
+ do { \
unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
libssh2_sha##digest_type##_ctx ctx; \
int i; \
- libssh2_sha##digest_type##_init(&ctx); \
+ (void)libssh2_sha##digest_type##_init(&ctx); \
for(i = 0; i < veccount; i++) { \
libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \
datavec[i].iov_len); \
@@ -692,7 +923,7 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \
SHA##digest_type##_DIGEST_LENGTH, \
signature, signature_len); \
- }
+ } while(0)
/*
@@ -709,7 +940,7 @@ hostkey_method_ssh_ecdsa_signv(LIBSSH2_SESSION * session,
void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = (libssh2_ecdsa_ctx *) (*abstract);
- libssh2_curve_type type = _libssh2_ecdsa_key_get_curve_type(ec_ctx);
+ libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_ctx);
int ret = 0;
if(type == LIBSSH2_EC_CURVE_NISTP256) {
@@ -737,9 +968,9 @@ static int
hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_ecdsa_ctx *keyctx = (libssh2_ecdsa_ctx *) (*abstract);
- (void) session;
+ (void)session;
- if(keyctx != NULL)
+ if(keyctx)
_libssh2_ecdsa_free(keyctx);
*abstract = NULL;
@@ -783,6 +1014,42 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521 = {
hostkey_method_ssh_ecdsa_dtor,
};
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp256_cert = {
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com",
+ SHA256_DIGEST_LENGTH,
+ NULL,
+ hostkey_method_ssh_ecdsa_initPEM,
+ hostkey_method_ssh_ecdsa_initPEMFromMemory,
+ NULL,
+ hostkey_method_ssh_ecdsa_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_ecdsa_dtor,
+};
+
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp384_cert = {
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com",
+ SHA384_DIGEST_LENGTH,
+ NULL,
+ hostkey_method_ssh_ecdsa_initPEM,
+ hostkey_method_ssh_ecdsa_initPEMFromMemory,
+ NULL,
+ hostkey_method_ssh_ecdsa_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_ecdsa_dtor,
+};
+
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521_cert = {
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com",
+ SHA512_DIGEST_LENGTH,
+ NULL,
+ hostkey_method_ssh_ecdsa_initPEM,
+ hostkey_method_ssh_ecdsa_initPEMFromMemory,
+ NULL,
+ hostkey_method_ssh_ecdsa_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_ecdsa_dtor,
+};
+
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
@@ -805,9 +1072,10 @@ hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
size_t hostkey_data_len,
void **abstract)
{
- const unsigned char *s;
- unsigned long len, key_len;
+ size_t key_len;
+ unsigned char *key;
libssh2_ed25519_ctx *ctx = NULL;
+ struct string_buf buf;
if(*abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
@@ -815,26 +1083,26 @@ hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
}
if(hostkey_data_len < 19) {
- _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
- "host key length too short");
+ _libssh2_debug((session, LIBSSH2_TRACE_ERROR,
+ "host key length too short"));
return -1;
}
- s = hostkey_data;
- len = _libssh2_ntohu32(s);
- s += 4;
+ buf.data = (unsigned char *)hostkey_data;
+ buf.dataptr = buf.data;
+ buf.len = hostkey_data_len;
- if(len != 11 || strncmp((char *) s, "ssh-ed25519", 11) != 0) {
+ if(_libssh2_match_string(&buf, "ssh-ed25519"))
return -1;
- }
-
- s += 11;
/* public key */
- key_len = _libssh2_ntohu32(s);
- s += 4;
+ if(_libssh2_get_string(&buf, &key, &key_len))
+ return -1;
+
+ if(!_libssh2_eob(&buf))
+ return -1;
- if(_libssh2_ed25519_new_public(&ctx, session, s, key_len) != 0) {
+ if(_libssh2_ed25519_new_public(&ctx, session, key, key_len) != 0) {
return -1;
}
@@ -850,9 +1118,9 @@ hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ed25519_initPEM(LIBSSH2_SESSION * session,
- const char *privkeyfile,
- unsigned const char *passphrase,
- void **abstract)
+ const char *privkeyfile,
+ unsigned const char *passphrase,
+ void **abstract)
{
libssh2_ed25519_ctx *ec_ctx = NULL;
int ret;
@@ -888,7 +1156,7 @@ hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session,
libssh2_ed25519_ctx *ed_ctx = NULL;
int ret;
- if(abstract != NULL && *abstract) {
+ if(abstract && *abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
*abstract = NULL;
}
@@ -901,7 +1169,7 @@ hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session,
return -1;
}
- if(abstract != NULL)
+ if(abstract)
*abstract = ed_ctx;
return 0;
@@ -920,7 +1188,7 @@ hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session,
size_t m_len, void **abstract)
{
libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract);
- (void) session;
+ (void)session;
if(sig_len < 19)
return -1;
@@ -943,11 +1211,11 @@ hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session,
- unsigned char **signature,
- size_t *signature_len,
- int veccount,
- const struct iovec datavec[],
- void **abstract)
+ unsigned char **signature,
+ size_t *signature_len,
+ int veccount,
+ const struct iovec datavec[],
+ void **abstract)
{
libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract);
@@ -969,7 +1237,7 @@ static int
hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_ed25519_ctx *keyctx = (libssh2_ed25519_ctx*) (*abstract);
- (void) session;
+ (void)session;
if(keyctx)
_libssh2_ed25519_free(keyctx);
@@ -991,7 +1259,19 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519 = {
hostkey_method_ssh_ed25519_dtor,
};
-#endif /*LIBSSH2_ED25519*/
+static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519_cert = {
+ "ssh-ed25519-cert-v01@openssh.com",
+ SHA256_DIGEST_LENGTH,
+ hostkey_method_ssh_ed25519_init,
+ hostkey_method_ssh_ed25519_initPEM,
+ hostkey_method_ssh_ed25519_initPEMFromMemory,
+ hostkey_method_ssh_ed25519_sig_verify,
+ hostkey_method_ssh_ed25519_signv,
+ NULL, /* encrypt */
+ hostkey_method_ssh_ed25519_dtor,
+};
+
+#endif /* LIBSSH2_ED25519 */
static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
@@ -999,12 +1279,23 @@ static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
&hostkey_method_ecdsa_ssh_nistp256,
&hostkey_method_ecdsa_ssh_nistp384,
&hostkey_method_ecdsa_ssh_nistp521,
+ &hostkey_method_ecdsa_ssh_nistp256_cert,
+ &hostkey_method_ecdsa_ssh_nistp384_cert,
+ &hostkey_method_ecdsa_ssh_nistp521_cert,
#endif
#if LIBSSH2_ED25519
&hostkey_method_ssh_ed25519,
+ &hostkey_method_ssh_ed25519_cert,
#endif
#if LIBSSH2_RSA
+#if LIBSSH2_RSA_SHA2
+ &hostkey_method_ssh_rsa_sha2_512,
+ &hostkey_method_ssh_rsa_sha2_256,
+#endif /* LIBSSH2_RSA_SHA2 */
+#if LIBSSH2_RSA_SHA1
&hostkey_method_ssh_rsa,
+ &hostkey_method_ssh_rsa_cert,
+#endif /* LIBSSH2_RSA_SHA1 */
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
&hostkey_method_ssh_dss,
@@ -1107,7 +1398,7 @@ static int hostkey_type(const unsigned char *hostkey, size_t len)
}
/*
- * libssh2_session_hostkey()
+ * libssh2_session_hostkey
*
* Returns the server key and length.
*