first commit
This commit is contained in:
commit
32a7ba8e8f
168 files changed
+123856
No files matched your search
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# Run against the exact bundled libssh2 archive produced by the Cargo build.
|
||||
set -eu
|
||||
if [ "$#" -ne 1 ] || [ ! -f "$1" ]; then
|
||||
echo "Usage: $0 /absolute/path/to/target/.../out/build/libssh2.a" >&2
|
||||
exit 2
|
||||
fi
|
||||
test_root=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
test_temp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_temp"' EXIT HUP INT TERM
|
||||
"${CC:-cc}" -std=c99 -O2 -DNDEBUG -Wall -Wextra -Werror \
|
||||
-I"$test_root/../libssh2/include" \
|
||||
"$test_root/security-regression.c" "$1" -lssl -lcrypto -lz \
|
||||
-o "$test_temp/security-regression"
|
||||
"$test_temp/security-regression"
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/* Targeted runtime checks for the vendored libssh2 security backports.
|
||||
* SPDX-License-Identifier: MIT
|
||||
* This program deliberately supplies boundary lengths, without any network.
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "libssh2.h"
|
||||
|
||||
/* Internal function from the statically linked, patched OpenSSL backend. */
|
||||
extern int _libssh2_cipher_crypt(EVP_CIPHER_CTX **ctx,
|
||||
const EVP_CIPHER *(*algo)(void),
|
||||
int encrypt, unsigned char *block,
|
||||
size_t blocksize, int firstlast);
|
||||
|
||||
static int check_crypto_bounds(void)
|
||||
{
|
||||
unsigned char buffer[EVP_MAX_BLOCK_LENGTH + 32];
|
||||
unsigned char original[sizeof(buffer)];
|
||||
size_t length;
|
||||
memset(buffer, 0xa5, sizeof(buffer));
|
||||
memcpy(original, buffer, sizeof(buffer));
|
||||
|
||||
/* A complete AES-GCM block requires 4 bytes of AAD plus a 16-byte tag.
|
||||
* A null context makes an accidental call into OpenSSL fail immediately;
|
||||
* a correct bounds check rejects these inputs before touching it. */
|
||||
for(length = 0; length < 20; length++) {
|
||||
if(_libssh2_cipher_crypt(NULL, EVP_aes_128_gcm, 0, buffer,
|
||||
length, 3) != 1)
|
||||
return 1;
|
||||
}
|
||||
if(_libssh2_cipher_crypt(NULL, EVP_aes_128_gcm, 0, buffer,
|
||||
sizeof(buffer), 3) != 1)
|
||||
return 1;
|
||||
if(_libssh2_cipher_crypt(NULL, EVP_aes_128_gcm, 0, buffer,
|
||||
SIZE_MAX, 3) != 1)
|
||||
return 1;
|
||||
return memcmp(buffer, original, sizeof(buffer)) != 0;
|
||||
}
|
||||
|
||||
static int check_username_bounds(void)
|
||||
{
|
||||
LIBSSH2_SESSION *session = libssh2_session_init();
|
||||
int failure = 0;
|
||||
if(!session)
|
||||
return 1;
|
||||
if(libssh2_userauth_list(session, "x", UINT_MAX) != NULL ||
|
||||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_PROTO)
|
||||
failure = 1;
|
||||
if(libssh2_userauth_password_ex(session, "x", UINT_MAX, "p", 1,
|
||||
NULL) != LIBSSH2_ERROR_PROTO)
|
||||
failure = 1;
|
||||
libssh2_session_free(session);
|
||||
return failure;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int failure;
|
||||
if(libssh2_init(0) != 0)
|
||||
return 1;
|
||||
failure = check_crypto_bounds() | check_username_bounds();
|
||||
libssh2_exit();
|
||||
if(failure) {
|
||||
fputs("libssh2 security boundary regression failed\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
puts("libssh2 security boundaries: AES-GCM short/oversized blocks and overflowing username lengths PASS");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user