コード例 #1
0
/*
 * Test if the continuously growing buffer size never exceeds 2 time its
 * real capacity
 */
static void *thread_growing_buffer(void *threadid)
{
    ssh_buffer buffer = NULL;
    int i;

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    for (i = 0; i < BUFFER_LIMIT; ++i) {
        ssh_buffer_add_data(buffer,"A",1);
        if (buffer->used >= 128) {
            if (ssh_buffer_get_len(buffer) * 2 < buffer->allocated) {
                assert_true(ssh_buffer_get_len(buffer) * 2 >= buffer->allocated);
            }
        }
    }

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
コード例 #2
0
static void *thread_ssh_buffer_add_format(void *threadid)
{
    ssh_buffer buffer = NULL;
    uint8_t b;
    uint16_t w;
    uint32_t d;
    uint64_t q;
    ssh_string s = NULL;
    int rc;
    size_t len;
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
        "\xac\xbd\xce\xdf"
        "\x00\x00\x00\x06" "libssh"
        "\x00\x00\x00\x05" "rocks"
        "So much"
        "Fun!";

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    b = 0x42;
    w = 0x1337;
    d = 0xbadc0de;
    q = 0x13243546acbdcedf;
    s = ssh_string_from_char("libssh");
    rc = ssh_buffer_pack(buffer,
                         "bwdqSsPt",
                         b,
                         w,
                         d,
                         q,
                         s,
                         "rocks",
                         7,
                         "So much",
                         "Fun!");
    assert_int_equal(rc, SSH_OK);

    len = ssh_buffer_get_len(buffer);
    assert_int_equal(len, sizeof(verif) - 1);
    assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);

    SSH_STRING_FREE(s);

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
コード例 #3
0
static void *thread_ssh_buffer_get_format_error(void *threadid)
{
    ssh_buffer buffer = NULL;
    uint8_t b = 0;
    uint16_t w = 0;
    uint32_t d = 0;
    uint64_t q = 0;
    ssh_string s = NULL;
    char *s1 = NULL, *s2 = NULL;
    int rc;
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
        "\xac\xbd\xce\xdf"
        "\x00\x00\x00\x06" "libssh"
        "\x00\x00\x00\x05" "rocks"
        "So much";

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1);
    assert_int_equal(rc, SSH_OK);
    rc = ssh_buffer_unpack(buffer,
                           "bwdqSsPb",
                           &b,
                           &w,
                           &d,
                           &q,
                           &s,
                           &s1,
                           (size_t)7,
                           &s2,
                           &b);
    assert_int_equal(rc, SSH_ERROR);

    assert_null(s);
    assert_null(s1);
    assert_null(s2);

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
コード例 #4
0
static void *thread_buffer_pack_badformat(void *threadid)
{
    ssh_buffer buffer = NULL;
    uint8_t b = 42;
    int rc;

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    /* first with missing format */
    rc = ssh_buffer_pack(buffer, "b", b, b);
    assert_int_equal(rc, SSH_ERROR);
    ssh_buffer_reinit(buffer);

    /* with additional format */
    rc = ssh_buffer_pack(buffer, "bb", b);
    /* check that we detect the missing parameter */
    assert_int_equal(rc, SSH_ERROR);

    /* unpack with missing format */
    ssh_buffer_reinit(buffer);

    rc = ssh_buffer_pack(buffer, "bb", 42, 43);
    assert_int_equal(rc, SSH_OK);

    rc = ssh_buffer_unpack(buffer, "b", &b, &b);
    assert_int_equal(rc, SSH_ERROR);

    /* not doing the test with additional format as
     * it could crash the process */

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
コード例 #5
0
/*
 * Test the behavior of ssh_buffer_prepend_data
 */
static void *thread_buffer_prepend(void *threadid)
{
    ssh_buffer buffer = NULL;
    uint32_t v;

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    ssh_buffer_add_data(buffer, "abcdef", 6);
    ssh_buffer_prepend_data(buffer, "xyz", 3);
    assert_int_equal(ssh_buffer_get_len(buffer), 9);
    assert_memory_equal(ssh_buffer_get(buffer),  "xyzabcdef", 9);

    /* Now remove 4 bytes and see if we can replace them */
    ssh_buffer_get_u32(buffer, &v);
    assert_int_equal(ssh_buffer_get_len(buffer), 5);
    assert_memory_equal(ssh_buffer_get(buffer), "bcdef", 5);

    ssh_buffer_prepend_data(buffer, "aris", 4);
    assert_int_equal(ssh_buffer_get_len(buffer), 9);
    assert_memory_equal(ssh_buffer_get(buffer), "arisbcdef", 9);

    /* same thing but we add 5 bytes now */
    ssh_buffer_get_u32(buffer, &v);
    assert_int_equal(ssh_buffer_get_len(buffer), 5);
    assert_memory_equal(ssh_buffer_get(buffer), "bcdef", 5);

    ssh_buffer_prepend_data(buffer, "12345", 5);
    assert_int_equal(ssh_buffer_get_len(buffer), 10);
    assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10);

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
コード例 #6
0
/*
 * Test if the continuously growing buffer size never exceeds 2 time its
 * real capacity, when we remove 1 byte after each call (sliding window)
 */
static void *thread_growing_buffer_shifting(void *threadid)
{
    ssh_buffer buffer;
    int i;
    unsigned char c;

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);


    for (i = 0; i < 1024; ++i) {
        ssh_buffer_add_data(buffer,"S",1);
    }

    for (i = 0; i < BUFFER_LIMIT; ++i) {
        ssh_buffer_get_u8(buffer,&c);
        ssh_buffer_add_data(buffer,"A",1);
        if (buffer->used >= 128) {
            if (ssh_buffer_get_len(buffer) * 4 < buffer->allocated) {
                assert_true(ssh_buffer_get_len(buffer) * 4 >= buffer->allocated);
                /* Teardown */
                SSH_BUFFER_FREE(buffer);
                pthread_exit(NULL);
            }
        }
    }

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
コード例 #7
0
ファイル: pki.c プロジェクト: codinn/libssh
/*
 * This function signs the session id as a string then
 * the content of sigbuf */
ssh_string ssh_pki_do_sign(ssh_session session,
                           ssh_buffer sigbuf,
                           const ssh_key privkey) {
    struct ssh_crypto_struct *crypto =
        session->current_crypto ? session->current_crypto :
                                  session->next_crypto;
    ssh_signature sig = NULL;
    ssh_string sig_blob;
    ssh_string session_id;
    int rc;

    if (privkey == NULL || !ssh_key_is_private(privkey)) {
        return NULL;
    }

    session_id = ssh_string_new(crypto->digest_len);
    if (session_id == NULL) {
        return NULL;
    }
    ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);

    if (privkey->type == SSH_KEYTYPE_ECDSA) {
#ifdef HAVE_ECC
        unsigned char ehash[EVP_DIGEST_LEN] = {0};
        uint32_t elen;
        EVPCTX ctx;

        ctx = evp_init(privkey->ecdsa_nid);
        if (ctx == NULL) {
            ssh_string_free(session_id);
            return NULL;
        }

        evp_update(ctx, session_id, ssh_string_len(session_id) + 4);
        evp_update(ctx, ssh_buffer_get(sigbuf), ssh_buffer_get_len(sigbuf));
        evp_final(ctx, ehash, &elen);

#ifdef DEBUG_CRYPTO
        ssh_print_hexa("Hash being signed", ehash, elen);
#endif

        sig = pki_do_sign(privkey, ehash, elen);
#endif
    } else if (privkey->type == SSH_KEYTYPE_ED25519){
        ssh_buffer buf;

        buf = ssh_buffer_new();
        if (buf == NULL) {
            ssh_string_free(session_id);
            return NULL;
        }

        ssh_buffer_set_secure(buf);
        rc = ssh_buffer_pack(buf,
                             "SP",
                             session_id,
                             ssh_buffer_get_len(sigbuf), ssh_buffer_get(sigbuf));
        if (rc != SSH_OK) {
            ssh_string_free(session_id);
            ssh_buffer_free(buf);
            return NULL;
        }

        sig = pki_do_sign(privkey,
                          ssh_buffer_get(buf),
                          ssh_buffer_get_len(buf));
        ssh_buffer_free(buf);
    } else {
        unsigned char hash[SHA_DIGEST_LEN] = {0};
        SHACTX ctx;

        ctx = sha1_init();
        if (ctx == NULL) {
            ssh_string_free(session_id);
            return NULL;
        }

        sha1_update(ctx, session_id, ssh_string_len(session_id) + 4);
        sha1_update(ctx, ssh_buffer_get(sigbuf), ssh_buffer_get_len(sigbuf));
        sha1_final(hash, ctx);

#ifdef DEBUG_CRYPTO
        ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
#endif

        sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN);
    }
    ssh_string_free(session_id);
    if (sig == NULL) {
        return NULL;
    }

    rc = ssh_pki_export_signature_blob(sig, &sig_blob);
    ssh_signature_free(sig);
    if (rc < 0) {
        return NULL;
    }

    return sig_blob;
}
コード例 #8
0
/** @internal
 * @brief Import a private key in OpenSSH (new) format. This format is
 * typically used with ed25519 keys but can be used for others.
 */
ssh_key ssh_pki_openssh_privkey_import(const char *text_key,
                                       const char *passphrase,
                                       ssh_auth_callback auth_fn,
                                       void *auth_data)
{
    const char *ptr=text_key;
    const char *end;
    char *base64;
    int cmp;
    int rc;
    int i;
    ssh_buffer buffer = NULL, privkey_buffer=NULL;
    char *magic = NULL, *ciphername = NULL, *kdfname = NULL;
    uint32_t nkeys = 0, checkint1, checkint2;
    ssh_string kdfoptions = NULL;
    ssh_string pubkey0 = NULL;
    ssh_string privkeys = NULL;
    ssh_string comment = NULL;
    ssh_key key = NULL;
    uint8_t padding;

    cmp = strncmp(ptr, OPENSSH_HEADER_BEGIN, strlen(OPENSSH_HEADER_BEGIN));
    if (cmp != 0){
        SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (no header)");
        goto error;
    }
    ptr += strlen(OPENSSH_HEADER_BEGIN);
    while(ptr[0] != '\0' && !isspace((int)ptr[0])) {
        ptr++;
    }
    end = strstr(ptr, OPENSSH_HEADER_END);
    if (end == NULL){
        SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (no footer)");
        goto error;
    }
    base64 = malloc(end - ptr + 1);
    if (base64 == NULL){
        goto error;
    }
    for (i = 0; ptr < end; ptr++){
        if (!isspace((int)ptr[0])) {
            base64[i] = ptr[0];
            i++;
        }
    }
    base64[i] = '\0';
    buffer = base64_to_bin(base64);
    SAFE_FREE(base64);
    if (buffer == NULL){
        SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (base64 error)");
        goto error;
    }
    rc = ssh_buffer_unpack(buffer, "PssSdSS",
                           strlen(OPENSSH_AUTH_MAGIC) + 1,
                           &magic,
                           &ciphername,
                           &kdfname,
                           &kdfoptions,
                           &nkeys,
                           &pubkey0,
                           &privkeys);
    if (rc == SSH_ERROR){
        SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (unpack error)");
        goto error;
    }
    cmp = strncmp(magic, OPENSSH_AUTH_MAGIC, strlen(OPENSSH_AUTH_MAGIC));
    if (cmp != 0){
        SSH_LOG(SSH_LOG_WARN, "Not an OpenSSH private key (bad magic)");
        goto error;
    }
    ssh_pki_log("Opening OpenSSH private key: ciphername: %s, kdf: %s, nkeys: %d\n", ciphername, kdfname, nkeys);
    if (nkeys != 1){
        SSH_LOG(SSH_LOG_WARN, "Opening OpenSSH private key: only 1 key supported (%d available)", nkeys);
        goto error;
    }
    rc = pki_private_key_decrypt(privkeys,
                                 passphrase,
                                 ciphername,
                                 kdfname,
                                 kdfoptions,
                                 auth_fn,
                                 auth_data);
    if (rc == SSH_ERROR){
        goto error;
    }

    privkey_buffer = ssh_buffer_new();
    if (privkey_buffer == NULL) {
        rc = SSH_ERROR;
        goto error;
    }

    ssh_buffer_set_secure(privkey_buffer);
    ssh_buffer_add_data(privkey_buffer,
                        ssh_string_data(privkeys),
                        ssh_string_len(privkeys));

    rc = ssh_buffer_unpack(privkey_buffer, "dd", &checkint1, &checkint2);
    if (rc == SSH_ERROR || checkint1 != checkint2){
        SSH_LOG(SSH_LOG_WARN, "OpenSSH private key unpack error (correct password?)");
        goto error;
    }
    rc = pki_openssh_import_privkey_blob(privkey_buffer, &key);
    if (rc == SSH_ERROR){
        goto error;
    }
    comment = buffer_get_ssh_string(privkey_buffer);
    SAFE_FREE(comment);
    /* verify that the remaining data is correct padding */
    for (i=1; buffer_get_rest_len(privkey_buffer) > 0; ++i){
        buffer_get_u8(privkey_buffer, &padding);
        if (padding != i){
            ssh_key_free(key);
            key = NULL;
            ssh_pki_log("Invalid padding");
            goto error;
        }
    }
error:
    if(buffer != NULL){
        ssh_buffer_free(buffer);
        buffer = NULL;
    }
    if(privkey_buffer != NULL){
        ssh_buffer_free(privkey_buffer);
        privkey_buffer = NULL;
    }
    SAFE_FREE(magic);
    SAFE_FREE(ciphername);
    SAFE_FREE(kdfname);
    SAFE_FREE(kdfoptions);
    SAFE_FREE(pubkey0);
    SAFE_FREE(privkeys);
    return key;
}
コード例 #9
0
static void *thread_ssh_buffer_get_format(void *threadid) {
    ssh_buffer buffer;
    uint8_t b = 0;
    uint16_t w = 0;
    uint32_t d = 0;
    uint64_t q = 0;
    ssh_string s = NULL;
    char *s1 = NULL, *s2 = NULL;
    int rc;
    size_t len;
    uint8_t verif[] = "\x42\x13\x37\x0b\xad\xc0\xde\x13\x24\x35\x46"
        "\xac\xbd\xce\xdf"
        "\x00\x00\x00\x06" "libssh"
        "\x00\x00\x00\x05" "rocks"
        "So much";

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    rc = ssh_buffer_add_data(buffer, verif, sizeof(verif) - 1);
    assert_int_equal(rc, SSH_OK);

    rc = ssh_buffer_unpack(buffer,
                           "bwdqSsP",
                           &b,
                           &w,
                           &d,
                           &q,
                           &s,
                           &s1,
                           (size_t)7,
                           &s2);
    assert_int_equal(rc, SSH_OK);

    assert_int_equal(b, 0x42);
    assert_int_equal(w, 0x1337);

    assert_true(d == 0xbadc0de);
    assert_true(q == 0x13243546acbdcedf);

    assert_non_null(s);
    assert_int_equal(ssh_string_len(s), 6);
    assert_memory_equal(ssh_string_data(s), "libssh", 6);

    assert_non_null(s1);
    assert_string_equal(s1, "rocks");

    assert_non_null(s2);
    assert_memory_equal(s2, "So much", 7);

    len = ssh_buffer_get_len(buffer);
    assert_int_equal(len, 0);
    SAFE_FREE(s);
    SAFE_FREE(s1);
    SAFE_FREE(s2);

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}