1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-12-08 03:42:13 +03:00

Add support for ECDSA keys and host keys (#41)

This commit lands full ECDSA key support when using the OpenSSL
backend. Which includes:

New KEX methods:
ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521

Can now read OpenSSL formatted ECDSA key files.

Now supports known host keys of type ecdsa-sha2-nistp256.

New curve types:
NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1

Default host key preferred ordering is now nistp256, nistp384,
nistp521, rsa, dss.

Ref: https://github.com/libssh2/libssh2/issues/41

Closes https://github.com/libssh2/libssh2/pull/206
This commit is contained in:
Will Cosgrove
2017-08-31 14:57:40 -07:00
committed by Viktor Szakats
parent bcd492163b
commit aba34f5f56
13 changed files with 2087 additions and 110 deletions

View File

@@ -50,6 +50,10 @@ COPY ssh_host_rsa_key /tmp/etc/ssh/ssh_host_rsa_key
RUN mv /tmp/etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_rsa_key
RUN chmod 600 /etc/ssh/ssh_host_rsa_key
COPY ssh_host_ecdsa_key /tmp/etc/ssh/ssh_host_ecdsa_key
RUN mv /tmp/etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key
RUN chmod 600 /etc/ssh/ssh_host_ecdsa_key
RUN adduser --disabled-password --gecos 'Test user for libssh2 integration tests' libssh2
RUN echo 'libssh2:my test password' | chpasswd

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKdqGrp+52U1ehslMI4fX0cmvgHFmKSkMzQGmj6B07ecoAoGCCqGSM49
AwEHoUQDQgAEL7+zLJ4okP10LZkf1DuIkZF5HhgzetQIyxLKeTJeiN19IKUYIxjs
m9aW3fQRKNi/GhN9JEbHpa9qpgr+8+hhDg==
-----END EC PRIVATE KEY-----

View File

@@ -4,7 +4,7 @@
#include <stdio.h>
const char *EXPECTED_HOSTKEY =
const char *EXPECTED_RSA_HOSTKEY =
"AAAAB3NzaC1yc2EAAAABIwAAAQEArrr/JuJmaZligyfS8vcNur+mWR2ddDQtVdhHzdKU"
"UoR6/Om6cvxpe61H1YZO1xCpLUBXmkki4HoNtYOpPB2W4V+8U4BDeVBD5crypEOE1+7B"
"Am99fnEDxYIOZq2/jTP0yQmzCpWYS3COyFmkOL7sfX1wQMeW5zQT2WKcxC6FSWbhDqrB"
@@ -12,6 +12,10 @@ const char *EXPECTED_HOSTKEY =
"i6ELfP3r+q6wdu0P4jWaoo3De1aYxnToV/ldXykpipON4NPamsb6Ph2qlJQKypq7J4iQ"
"gkIIbCU1A31+4ExvcIVoxLQw/aTSbw==";
const char *EXPECTED_ECDSA_HOSTKEY =
"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC+/syyeKJD9dC2ZH"
"9Q7iJGReR4YM3rUCMsSynkyXojdfSClGCMY7JvWlt30ESjYvxoTfSRGx6WvaqYK/vPoYQ4=";
int test(LIBSSH2_SESSION *session)
{
int rc;
@@ -26,14 +30,19 @@ int test(LIBSSH2_SESSION *session)
return 1;
}
if (type != LIBSSH2_HOSTKEY_TYPE_RSA) {
/* Hostkey configured in docker container is RSA */
fprintf(stderr, "Wrong type of hostkey\n");
if (type == LIBSSH2_HOSTKEY_TYPE_ECDSA) {
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_ECDSA_HOSTKEY, strlen(EXPECTED_ECDSA_HOSTKEY));
}
else if (type == LIBSSH2_HOSTKEY_TYPE_RSA) {
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_RSA_HOSTKEY, strlen(EXPECTED_RSA_HOSTKEY));
}
else {
fprintf(stderr, "Unexpected type of hostkey: %i\n", type);
return 1;
}
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
EXPECTED_HOSTKEY, strlen(EXPECTED_HOSTKEY));
if (rc != 0) {
print_last_session_error("libssh2_base64_decode");
return 1;

View File

@@ -5,7 +5,7 @@
#include <stdio.h>
const char *EXPECTED_HOSTKEY =
const char *EXPECTED_RSA_HOSTKEY =
"AAAAB3NzaC1yc2EAAAABIwAAAQEArrr/JuJmaZligyfS8vcNur+mWR2ddDQtVdhHzdKU"
"UoR6/Om6cvxpe61H1YZO1xCpLUBXmkki4HoNtYOpPB2W4V+8U4BDeVBD5crypEOE1+7B"
"Am99fnEDxYIOZq2/jTP0yQmzCpWYS3COyFmkOL7sfX1wQMeW5zQT2WKcxC6FSWbhDqrB"
@@ -13,13 +13,27 @@ const char *EXPECTED_HOSTKEY =
"i6ELfP3r+q6wdu0P4jWaoo3De1aYxnToV/ldXykpipON4NPamsb6Ph2qlJQKypq7J4iQ"
"gkIIbCU1A31+4ExvcIVoxLQw/aTSbw==";
const char *EXPECTED_MD5_HASH_DIGEST = "0C0ED1A5BB10275F76924CE187CE5C5E";
const char *EXPECTED_ECDSA_HOSTKEY =
"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC+/syyeKJD9dC2ZH"
"9Q7iJGReR4YM3rUCMsSynkyXojdfSClGCMY7JvWlt30ESjYvxoTfSRGx6WvaqYK/vPoYQ4=";
const char *EXPECTED_SHA1_HASH_DIGEST =
const char *EXPECTED_RSA_MD5_HASH_DIGEST = "0C0ED1A5BB10275F76924CE187CE5C5E";
const char *EXPECTED_RSA_SHA1_HASH_DIGEST =
"F3CD59E2913F4422B80F7B0A82B2B89EAE449387";
const char *EXPECTED_RSA_SHA256_HASH_DIGEST = "92E3DA49DF3C7F99A828F505ED8239397A5D1F62914459760F878F7510F563A3";
const char *EXPECTED_ECDSA_MD5_HASH_DIGEST = "0402E4D897580BBC911379CBD88BCD3D";
const char *EXPECTED_ECDSA_SHA1_HASH_DIGEST =
"12FDAD1E3B31B10BABB00F2A8D1B9A62C326BD2F";
const char *EXPECTED_ECDSA_SHA256_HASH_DIGEST = "56FCD975B166C3F0342D0036E44C311A86C0EAE40713B53FC776369BAE7F5264";
const int MD5_HASH_SIZE = 16;
const int SHA1_HASH_SIZE = 20;
const int SHA256_HASH_SIZE = 32;
static void calculate_digest(const char *hash, size_t hash_len, char *buffer,
size_t buffer_len)
@@ -39,34 +53,111 @@ int test(LIBSSH2_SESSION *session)
const char *md5_hash;
const char *sha1_hash;
const char *sha256_hash;
int type;
size_t len;
md5_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
if (md5_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_MD5)");
const char *hostkey = libssh2_session_hostkey(session, &len, &type);
if (hostkey == NULL) {
print_last_session_error("libssh2_session_hostkey");
return 1;
}
calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ);
if (type == LIBSSH2_HOSTKEY_TYPE_ECDSA) {
if (strcmp(buf, EXPECTED_MD5_HASH_DIGEST) != 0) {
fprintf(stderr, "MD5 hash not as expected - digest %s != %s\n", buf,
EXPECTED_MD5_HASH_DIGEST);
return 1;
}
md5_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
if (md5_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_MD5)");
return 1;
}
sha1_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
if (sha1_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA1)");
return 1;
}
calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ);
calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ);
if (strcmp(buf, EXPECTED_ECDSA_MD5_HASH_DIGEST) != 0) {
fprintf(stderr, "ECDSA MD5 hash not as expected - digest %s != %s\n", buf,
EXPECTED_ECDSA_MD5_HASH_DIGEST);
return 1;
}
if (strcmp(buf, EXPECTED_SHA1_HASH_DIGEST) != 0) {
fprintf(stderr, "SHA1 hash not as expected - digest %s != %s\n", buf,
EXPECTED_SHA1_HASH_DIGEST);
sha1_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
if (sha1_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA1)");
return 1;
}
calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ);
if (strcmp(buf, EXPECTED_ECDSA_SHA1_HASH_DIGEST) != 0) {
fprintf(stderr, "ECDSA SHA1 hash not as expected - digest %s != %s\n", buf,
EXPECTED_ECDSA_SHA1_HASH_DIGEST);
return 1;
}
sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256);
if (sha256_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)");
return 1;
}
calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ);
if (strcmp(buf, EXPECTED_ECDSA_SHA256_HASH_DIGEST) != 0) {
fprintf(stderr, "ECDSA SHA256 hash not as expected - digest %s != %s\n", buf,
EXPECTED_ECDSA_SHA256_HASH_DIGEST);
return 1;
}
} else if ( type == LIBSSH2_HOSTKEY_TYPE_RSA ) {
md5_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
if (md5_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_MD5)");
return 1;
}
calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ);
if (strcmp(buf, EXPECTED_RSA_MD5_HASH_DIGEST) != 0) {
fprintf(stderr, "MD5 hash not as expected - digest %s != %s\n", buf,
EXPECTED_RSA_MD5_HASH_DIGEST);
return 1;
}
sha1_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
if (sha1_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA1)");
return 1;
}
calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ);
if (strcmp(buf, EXPECTED_RSA_SHA1_HASH_DIGEST) != 0) {
fprintf(stderr, "SHA1 hash not as expected - digest %s != %s\n", buf,
EXPECTED_RSA_SHA1_HASH_DIGEST);
return 1;
}
sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256);
if (sha256_hash == NULL) {
print_last_session_error(
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)");
return 1;
}
calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ);
if (strcmp(buf, EXPECTED_RSA_SHA256_HASH_DIGEST) != 0) {
fprintf(stderr, "SHA256 hash not as expected - digest %s != %s\n", buf,
EXPECTED_RSA_SHA256_HASH_DIGEST);
return 1;
}
} else {
fprintf(stderr, "Unexpected type of hostkey: %i\n", type);
return 1;
}