コード例 #1
0
ファイル: server.c プロジェクト: alejom200/tmate
static int server_set_kex(ssh_session session) {
  struct ssh_kex_struct *server = &session->next_crypto->server_kex;
  int i, j, rc;
  const char *wanted;
  char hostkeys[64] = {0};
  enum ssh_keytypes_e keytype;
  size_t len;

  ZERO_STRUCTP(server);
  ssh_get_random(server->cookie, 16, 0);

#ifdef HAVE_ECC
  if (session->srv.ecdsa_key != NULL) {
      snprintf(hostkeys, sizeof(hostkeys),
               "%s", session->srv.ecdsa_key->type_c);
  }
#endif
  if (session->srv.dsa_key != NULL) {
      len = strlen(hostkeys);
      keytype = ssh_key_type(session->srv.dsa_key);

      snprintf(hostkeys + len, sizeof(hostkeys) - len,
               ",%s", ssh_key_type_to_char(keytype));
  }
  if (session->srv.rsa_key != NULL) {
      len = strlen(hostkeys);
      keytype = ssh_key_type(session->srv.rsa_key);

      snprintf(hostkeys + len, sizeof(hostkeys) - len,
               ",%s", ssh_key_type_to_char(keytype));
  }

  if (strlen(hostkeys) == 0) {
      return -1;
  }

  rc = ssh_options_set_algo(session,
                            SSH_HOSTKEYS,
                            hostkeys[0] == ',' ? hostkeys + 1 : hostkeys);
  if (rc < 0) {
      return -1;
  }

  for (i = 0; i < 10; i++) {
    if ((wanted = session->opts.wanted_methods[i]) == NULL) {
      wanted = ssh_kex_get_supported_method(i);
    }
    server->methods[i] = strdup(wanted);
    if (server->methods[i] == NULL) {
      for (j = 0; j < i; j++) {
        SAFE_FREE(server->methods[j]);
      }
      return -1;
    }
  }

  return 0;
}
コード例 #2
0
ファイル: pki_crypto.c プロジェクト: rofl0r/libssh
ssh_key pki_publickey_from_privatekey(ssh_key privkey) {
    ssh_key pubkey = NULL;

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

    pubkey = ssh_key_new();
    if (pubkey == NULL) {
        return NULL;
    }
    pubkey->type = privkey->type;

    switch (pubkey->type) {
        case SSH_KEYTYPE_DSS:
            pubkey->dsa = DSA_new();
            if (pubkey->dsa == NULL) {
                goto fail;
            }
            pubkey->dsa->p = BN_dup(privkey->dsa->p);
            pubkey->dsa->q = BN_dup(privkey->dsa->q);
            pubkey->dsa->g = BN_dup(privkey->dsa->g);
            pubkey->dsa->pub_key = BN_dup(privkey->dsa->pub_key);
            if (pubkey->dsa->p == NULL ||
                    pubkey->dsa->q == NULL ||
                    pubkey->dsa->g == NULL ||
                    pubkey->dsa->pub_key == NULL) {
                goto fail;
            }
            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            pubkey->rsa = RSA_new();
            if (pubkey->rsa == NULL) {
                goto fail;
            }
            pubkey->rsa->e = BN_dup(privkey->rsa->e);
            pubkey->rsa->n = BN_dup(privkey->rsa->n);
            if (pubkey->rsa->e == NULL ||
                    pubkey->rsa->n == NULL) {
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ECDSA:
        case SSH_KEYTYPE_UNKNOWN:
            ssh_key_free(pubkey);
            return NULL;
    }
    pubkey->type_c = ssh_key_type_to_char(privkey->type);

    return pubkey;
fail:
    ssh_key_free(pubkey);

    return NULL;
}
コード例 #3
0
ファイル: pki.c プロジェクト: codinn/libssh
/**
 * @brief Generates a keypair.
 *
 * @param[in] type      Type of key to create
 *
 * @param[in] parameter Parameter to the creation of key:
 *                      rsa : length of the key in bits (e.g. 1024, 2048, 4096)
 *                      dsa : length of the key in bits (e.g. 1024, 2048, 3072)
 *                      ecdsa : bits of the key (e.g. 256, 384, 512)
 * @param[out] pkey     A pointer to store the allocated private key. You need
 *                      to free the memory.
 *
 * @return              SSH_OK on success, SSH_ERROR on error.
 *
 * @warning             Generating a key pair may take some time.
 */
int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
        ssh_key *pkey){
    int rc;
    ssh_key key = ssh_key_new();

    if (key == NULL) {
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;

    switch(type){
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            rc = pki_key_generate_rsa(key, parameter);
            if(rc == SSH_ERROR)
                goto error;
            break;
        case SSH_KEYTYPE_DSS:
            rc = pki_key_generate_dss(key, parameter);
            if(rc == SSH_ERROR)
                goto error;
            break;
        case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC
            rc = pki_key_generate_ecdsa(key, parameter);
            if (rc == SSH_ERROR) {
                goto error;
            }

            /* Update key type */
            key->type_c = ssh_pki_key_ecdsa_name(key);
            break;
#endif
        case SSH_KEYTYPE_ED25519:
            rc = pki_key_generate_ed25519(key);
            if (rc == SSH_ERROR) {
                goto error;
            }
            break;
        case SSH_KEYTYPE_DSS_CERT01:
        case SSH_KEYTYPE_RSA_CERT01:
        case SSH_KEYTYPE_UNKNOWN:
            goto error;
    }

    *pkey = key;
    return SSH_OK;
error:
    ssh_key_free(key);
    return SSH_ERROR;
}
コード例 #4
0
ファイル: torture_pki.c プロジェクト: dbussink/libssh
static void torture_pki_keytype(void **state) {
    enum ssh_keytypes_e type;
    const char *type_c;

    (void) state; /* unused */

    type = ssh_key_type(NULL);
    assert_true(type == SSH_KEYTYPE_UNKNOWN);

    type = ssh_key_type_from_name(NULL);
    assert_true(type == SSH_KEYTYPE_UNKNOWN);

    type = ssh_key_type_from_name("42");
    assert_true(type == SSH_KEYTYPE_UNKNOWN);

    type_c = ssh_key_type_to_char(SSH_KEYTYPE_UNKNOWN);
    assert_true(type_c == NULL);

    type_c = ssh_key_type_to_char(42);
    assert_true(type_c == NULL);
}
コード例 #5
0
ファイル: pki.c プロジェクト: codinn/libssh
static int pki_import_cert_buffer(ssh_buffer buffer,
                                  enum ssh_keytypes_e type,
                                  ssh_key *pkey) {
    ssh_buffer cert;
    ssh_string type_s;
    ssh_key key;
    int rc;

    key = ssh_key_new();
    if (key == NULL) {
        return SSH_ERROR;
    }
    cert = ssh_buffer_new();
    if (cert == NULL) {
        ssh_key_free(key);
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PUBLIC;

    /*
     * The cert blob starts with the key type as an ssh_string, but this
     * string has been read out of the buffer to identify the key type.
     * Simply add it again as first element before copying the rest.
     */
    type_s = ssh_string_from_char(key->type_c);
    if (type_s == NULL) {
        goto fail;
    }
    rc = ssh_buffer_add_ssh_string(cert, type_s);
    ssh_string_free(type_s);
    if (rc != 0) {
        goto fail;
    }

    rc = ssh_buffer_add_buffer(cert, buffer);
    if (rc != 0) {
        goto fail;
    }
    key->cert = (void*) cert;

    *pkey = key;
    return SSH_OK;

fail:
    ssh_key_free(key);
    ssh_buffer_free(cert);
    return SSH_ERROR;
}
コード例 #6
0
ファイル: pkd_daemon.c プロジェクト: ShiftMediaProject/libssh
static int pkd_auth_pubkey_cb(ssh_session s,
                              const char *user,
                              ssh_key key,
                              char state,
                              void *userdata) {
    (void) s;
    (void) user;
    (void) key;
    (void) state;
    (void) userdata;
    pkdout("pkd_auth_pubkey_cb keytype %s, state: %d\n",
           ssh_key_type_to_char(ssh_key_type(key)), state);
    if ((state == SSH_PUBLICKEY_STATE_NONE) ||
        (state == SSH_PUBLICKEY_STATE_VALID)) {
        return SSH_AUTH_SUCCESS;
    }
    return SSH_AUTH_DENIED;
}
コード例 #7
0
ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
        ssh_auth_callback auth_fn, void *auth_data)
{
    ssh_key key = NULL;
    mbedtls_pk_context *rsa = NULL;
    mbedtls_pk_context *ecdsa = NULL;
    ed25519_privkey *ed25519 = NULL;
    enum ssh_keytypes_e type;
    int valid;
    /* mbedtls pk_parse_key expects strlen to count the 0 byte */
    size_t b64len = strlen(b64_key) + 1;
    unsigned char tmp[MAX_PASSPHRASE_SIZE] = {0};

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
        return NULL;
    }

    switch (type) {
        case SSH_KEYTYPE_RSA:
            rsa = malloc(sizeof(mbedtls_pk_context));
            if (rsa == NULL) {
                return NULL;
            }

            mbedtls_pk_init(rsa);

            if (passphrase == NULL) {
                if (auth_fn) {
                    valid = auth_fn("Passphrase for private key:", (char *) tmp,
                            MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
                    if (valid < 0) {
                        return NULL;
                    }
                    /* TODO fix signedness and strlen */
                    valid = mbedtls_pk_parse_key(rsa,
                            (const unsigned char *) b64_key,
                            b64len, tmp,
                            strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
                } else {
                    valid = mbedtls_pk_parse_key(rsa,
                            (const unsigned char *) b64_key,
                            b64len, NULL,
                            0);
                }
            } else {
                valid = mbedtls_pk_parse_key(rsa,
                        (const unsigned char *) b64_key, b64len,
                        (const unsigned char *) passphrase,
                        strnlen(passphrase, MAX_PASSPHRASE_SIZE));
            }

            if (valid != 0) {
                char error_buf[100];
                mbedtls_strerror(valid, error_buf, 100);
                SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ECDSA:
            ecdsa = malloc(sizeof(mbedtls_pk_context));
            if (ecdsa == NULL) {
                return NULL;
            }

            mbedtls_pk_init(ecdsa);

            if (passphrase == NULL) {
                if (auth_fn) {
                    valid = auth_fn("Passphrase for private key:", (char *) tmp,
                            MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
                    if (valid < 0) {
                        return NULL;
                    }
                    valid = mbedtls_pk_parse_key(ecdsa,
                            (const unsigned char *) b64_key,
                            b64len, tmp,
                            strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
                } else {
                    valid = mbedtls_pk_parse_key(ecdsa,
                            (const unsigned char *) b64_key,
                            b64len, NULL,
                            0);
                }
            } else {
                valid = mbedtls_pk_parse_key(ecdsa,
                        (const unsigned char *) b64_key, b64len,
                        (const unsigned char *) passphrase,
                        strnlen(passphrase, MAX_PASSPHRASE_SIZE));
            }

            if (valid != 0) {
                char error_buf[100];
                mbedtls_strerror(valid, error_buf, 100);
                SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ED25519:
            /* Cannot open ed25519 keys with libmbedcrypto */
        default:
            SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d",
                    type);
            return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->rsa = rsa;
    if (ecdsa != NULL) {
        mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*ecdsa);

        key->ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
        if (key->ecdsa == NULL) {
            goto fail;
        }

        mbedtls_ecdsa_init(key->ecdsa);
        mbedtls_ecdsa_from_keypair(key->ecdsa, keypair);
        mbedtls_pk_free(ecdsa);
        SAFE_FREE(ecdsa);
    } else {
        key->ecdsa = NULL;
    }
    key->ed25519_privkey = ed25519;
    rsa = NULL;
    ecdsa = NULL;
    if (key->type == SSH_KEYTYPE_ECDSA) {
        key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
        key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
    }

    return key;
fail:
    ssh_key_free(key);
    if (rsa != NULL) {
        mbedtls_pk_free(rsa);
        SAFE_FREE(rsa);
    }
    if (ecdsa != NULL) {
        mbedtls_pk_free(ecdsa);
        SAFE_FREE(ecdsa);
    }
    return NULL;
}
コード例 #8
0
ファイル: pki.c プロジェクト: codinn/libssh
static int pki_import_pubkey_buffer(ssh_buffer buffer,
                                    enum ssh_keytypes_e type,
                                    ssh_key *pkey) {
    ssh_key key;
    int rc;

    key = ssh_key_new();
    if (key == NULL) {
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PUBLIC;

    switch (type) {
        case SSH_KEYTYPE_DSS:
            {
                ssh_string p;
                ssh_string q;
                ssh_string g;
                ssh_string pubkey;

                p = ssh_buffer_get_ssh_string(buffer);
                if (p == NULL) {
                    goto fail;
                }
                q = ssh_buffer_get_ssh_string(buffer);
                if (q == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);

                    goto fail;
                }
                g = ssh_buffer_get_ssh_string(buffer);
                if (g == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);

                    goto fail;
                }
                pubkey = ssh_buffer_get_ssh_string(buffer);
                if (pubkey == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);
                    ssh_string_burn(g);
                    ssh_string_free(g);

                    goto fail;
                }

                rc = pki_pubkey_build_dss(key, p, q, g, pubkey);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p));
                ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q));
                ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g));
#endif
                ssh_string_burn(p);
                ssh_string_free(p);
                ssh_string_burn(q);
                ssh_string_free(q);
                ssh_string_burn(g);
                ssh_string_free(g);
                ssh_string_burn(pubkey);
                ssh_string_free(pubkey);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            {
                ssh_string e;
                ssh_string n;

                e = ssh_buffer_get_ssh_string(buffer);
                if (e == NULL) {
                    goto fail;
                }
                n = ssh_buffer_get_ssh_string(buffer);
                if (n == NULL) {
                    ssh_string_burn(e);
                    ssh_string_free(e);

                    goto fail;
                }

                rc = pki_pubkey_build_rsa(key, e, n);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e));
                ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n));
#endif
                ssh_string_burn(e);
                ssh_string_free(e);
                ssh_string_burn(n);
                ssh_string_free(n);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC
            {
                ssh_string e;
                ssh_string i;
                int nid;

                i = ssh_buffer_get_ssh_string(buffer);
                if (i == NULL) {
                    goto fail;
                }
                nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i));
                ssh_string_free(i);
                if (nid == -1) {
                    goto fail;
                }


                e = ssh_buffer_get_ssh_string(buffer);
                if (e == NULL) {
                    goto fail;
                }

                rc = pki_pubkey_build_ecdsa(key, nid, e);
                ssh_string_burn(e);
                ssh_string_free(e);
                if (rc < 0) {
                    goto fail;
                }

                /* Update key type */
                key->type_c = ssh_pki_key_ecdsa_name(key);
            }
            break;
#endif
        case SSH_KEYTYPE_ED25519:
        {
            ssh_string pubkey = ssh_buffer_get_ssh_string(buffer);
            if (ssh_string_len(pubkey) != ED25519_PK_LEN) {
                SSH_LOG(SSH_LOG_WARN, "Invalid public key length");
                ssh_string_burn(pubkey);
                ssh_string_free(pubkey);
                goto fail;
            }

            key->ed25519_pubkey = malloc(ED25519_PK_LEN);
            if (key->ed25519_pubkey == NULL) {
                ssh_string_burn(pubkey);
                ssh_string_free(pubkey);
                goto fail;
            }

            memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_PK_LEN);
            ssh_string_burn(pubkey);
            ssh_string_free(pubkey);
        }
        break;
        case SSH_KEYTYPE_DSS_CERT01:
        case SSH_KEYTYPE_RSA_CERT01:
        case SSH_KEYTYPE_UNKNOWN:
        default:
            SSH_LOG(SSH_LOG_WARN, "Unknown public key protocol %d", type);
            goto fail;
    }

    *pkey = key;
    return SSH_OK;
fail:
    ssh_key_free(key);

    return SSH_ERROR;
}
コード例 #9
0
ファイル: pki_gcrypt.c プロジェクト: nviennot/libssh
ssh_key pki_private_key_from_base64(const char *b64_key,
                                    const char *passphrase,
                                    ssh_auth_callback auth_fn,
                                    void *auth_data)
{
    gcry_sexp_t dsa = NULL;
    gcry_sexp_t rsa = NULL;
    ssh_key key = NULL;
    enum ssh_keytypes_e type;
    int valid;

    /* needed for gcrypt initialization */
    if (ssh_init() < 0) {
        return NULL;
    }

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
        return NULL;
    }

    switch (type) {
    case SSH_KEYTYPE_DSS:
        if (passphrase == NULL) {
            if (auth_fn) {
                valid = b64decode_dsa_privatekey(b64_key, &dsa, auth_fn,
                                                 auth_data, "Passphrase for private key:");
            } else {
                valid = b64decode_dsa_privatekey(b64_key, &dsa, NULL, NULL,
                                                 NULL);
            }
        } else {
            valid = b64decode_dsa_privatekey(b64_key, &dsa, NULL, (void *)
                                             passphrase, NULL);
        }

        if (!valid) {
            SSH_LOG(SSH_LOG_WARN, "Parsing private key");
            goto fail;
        }
        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
        if (passphrase == NULL) {
            if (auth_fn) {
                valid = b64decode_rsa_privatekey(b64_key, &rsa, auth_fn,
                                                 auth_data, "Passphrase for private key:");
            } else {
                valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL, NULL,
                                                 NULL);
            }
        } else {
            valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL,
                                             (void *)passphrase, NULL);
        }

        if (!valid) {
            SSH_LOG(SSH_LOG_WARN, "Parsing private key");
            goto fail;
        }
        break;
    case SSH_KEYTYPE_ED25519:
    /* Cannot open ed25519 keys with libgcrypt */
    case SSH_KEYTYPE_ECDSA:
    case SSH_KEYTYPE_UNKNOWN:
    default:
        SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
        return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->dsa = dsa;
    key->rsa = rsa;

    return key;
fail:
    ssh_key_free(key);
    gcry_sexp_release(dsa);
    gcry_sexp_release(rsa);

    return NULL;
}
コード例 #10
0
ファイル: cockpitsshtransport.c プロジェクト: leospol/cockpit
static const gchar *
verify_knownhost (CockpitSshData *data)
{
  const gchar *ret = "unknown-hostkey";
  ssh_key key = NULL;
  unsigned char *hash = NULL;
  const char *type = NULL;
  int state;
  gsize len;

  data->host_key = get_knownhosts_line (data->session);
  if (data->host_key == NULL)
    {
      ret = "internal-error";
      goto done;
    }

  if (ssh_get_publickey (data->session, &key) != SSH_OK)
    {
      g_warning ("Couldn't look up ssh host key");
      ret = "internal-error";
      goto done;
    }

  type = ssh_key_type_to_char (ssh_key_type (key));
  if (type == NULL)
    {
      g_warning ("Couldn't lookup host key type");
      ret = "internal-error";
      goto done;
    }

  if (ssh_get_publickey_hash (key, SSH_PUBLICKEY_HASH_MD5, &hash, &len) < 0)
    {
      g_warning ("Couldn't hash ssh public key");
      ret = "internal-error";
      goto done;
    }
  else
    {
      data->host_fingerprint = ssh_get_hexa (hash, len);
      ssh_clean_pubkey_hash (&hash);
    }

  if (data->expect_key)
    {
      /* Only check that the host key matches this specifically */
      if (g_str_equal (data->host_key, data->expect_key))
        {
          g_debug ("%s: host key matched expected", data->logname);
          ret = NULL; /* success */
        }
      else
        {
          /* A empty expect_key is used by the frontend to force
             failure.  Don't warn about it.
          */
          if (data->expect_key[0])
            g_message ("%s: host key did not match expected", data->logname);
        }
    }
  else
    {
      if (ssh_options_set (data->session, SSH_OPTIONS_KNOWNHOSTS, data->knownhosts_file) != SSH_OK)
        {
          g_warning ("Couldn't set knownhosts file location");
          ret = "internal-error";
          goto done;
        }

      state = ssh_is_server_known (data->session);
      if (state == SSH_SERVER_KNOWN_OK)
        {
          g_debug ("%s: verified host key", data->logname);
          ret = NULL; /* success */
          goto done;
        }
      else if (state == SSH_SERVER_ERROR)
        {
          if (g_atomic_int_get (data->connecting))
            g_warning ("%s: couldn't check host key: %s", data->logname,
                       ssh_get_error (data->session));
          ret = "internal-error";
          goto done;
        }

      switch (state)
        {
        case SSH_SERVER_KNOWN_OK:
        case SSH_SERVER_ERROR:
          g_assert_not_reached ();
          break;
        case SSH_SERVER_KNOWN_CHANGED:
          g_message ("%s: %s host key for server has changed to: %s",
                     data->logname, type, data->host_fingerprint);
          break;
        case SSH_SERVER_FOUND_OTHER:
          g_message ("%s: host key for this server changed key type: %s",
                     data->logname, type);
          break;
        case SSH_SERVER_FILE_NOT_FOUND:
          g_debug ("Couldn't find the known hosts file");
          /* fall through */
        case SSH_SERVER_NOT_KNOWN:
          g_message ("%s: %s host key for server is not known: %s",
                     data->logname, type, data->host_fingerprint);
          break;
        }
    }

done:
  if (key)
    ssh_key_free (key);
  return ret;
}
コード例 #11
0
ファイル: pki_crypto.c プロジェクト: rofl0r/libssh
ssh_key pki_private_key_from_base64(ssh_session session,
                                    const char *b64_key,
                                    const char *passphrase) {
    BIO *mem = NULL;
    DSA *dsa = NULL;
    RSA *rsa = NULL;
    ssh_key key;
    enum ssh_keytypes_e type;

    /* needed for openssl initialization */
    if (ssh_init() < 0) {
        return NULL;
    }

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        ssh_set_error(session, SSH_FATAL, "Unknown or invalid private key.");
        return NULL;
    }

    mem = BIO_new_mem_buf((void*)b64_key, -1);

    switch (type) {
        case SSH_KEYTYPE_DSS:
            if (passphrase == NULL) {
                if (session->common.callbacks && session->common.callbacks->auth_function) {
                    dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, pem_get_password, session);
                } else {
                    /* openssl uses its own callback to get the passphrase here */
                    dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL);
                }
            } else {
                dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
            }

            BIO_free(mem);

            if (dsa == NULL) {
                ssh_set_error(session, SSH_FATAL,
                              "Parsing private key: %s",
                              ERR_error_string(ERR_get_error(), NULL));
                return NULL;
            }

            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            if (passphrase == NULL) {
                if (session->common.callbacks && session->common.callbacks->auth_function) {
                    rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, pem_get_password, session);
                } else {
                    /* openssl uses its own callback to get the passphrase here */
                    rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL);
                }
            } else {
                rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, (void *) passphrase);
            }

            BIO_free(mem);

            if (rsa == NULL) {
                ssh_set_error(session, SSH_FATAL,
                              "Parsing private key: %s",
                              ERR_error_string(ERR_get_error(),NULL));
                return NULL;
            }

            break;
        case SSH_KEYTYPE_ECDSA:
        case SSH_KEYTYPE_UNKNOWN:
            BIO_free(mem);
            ssh_set_error(session, SSH_FATAL,
                          "Unkown or invalid private key type %d", type);
            return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->dsa = dsa;
    key->rsa = rsa;

    return key;
fail:
    ssh_key_free(key);
    DSA_free(dsa);
    RSA_free(rsa);

    return NULL;
}
コード例 #12
0
ファイル: server.c プロジェクト: simonsj/libssh
int server_set_kex(ssh_session session)
{
  struct ssh_kex_struct *server = &session->next_crypto->server_kex;
  int i, j, rc;
  const char *wanted;
  char hostkeys[128] = {0};
  enum ssh_keytypes_e keytype;
  size_t len;
  int ok;

  ZERO_STRUCTP(server);

  ok = ssh_get_random(server->cookie, 16, 0);
  if (!ok) {
      ssh_set_error(session, SSH_FATAL, "PRNG error");
      return -1;
  }

  if (session->srv.ed25519_key != NULL) {
      snprintf(hostkeys,
               sizeof(hostkeys),
               "%s",
               ssh_key_type_to_char(ssh_key_type(session->srv.ed25519_key)));
  }
#ifdef HAVE_ECC
  if (session->srv.ecdsa_key != NULL) {
	  len = strlen(hostkeys);
      snprintf(hostkeys + len, sizeof(hostkeys) - len,
               ",%s", session->srv.ecdsa_key->type_c);
  }
#endif
#ifdef HAVE_DSA
  if (session->srv.dsa_key != NULL) {
      len = strlen(hostkeys);
      keytype = ssh_key_type(session->srv.dsa_key);

      snprintf(hostkeys + len, sizeof(hostkeys) - len,
               ",%s", ssh_key_type_to_char(keytype));
  }
#endif
  if (session->srv.rsa_key != NULL) {
      /* We support also the SHA2 variants */
      len = strlen(hostkeys);
      snprintf(hostkeys + len, sizeof(hostkeys) - len,
               ",rsa-sha2-512,rsa-sha2-256");

      len = strlen(hostkeys);
      keytype = ssh_key_type(session->srv.rsa_key);

      snprintf(hostkeys + len, sizeof(hostkeys) - len,
               ",%s", ssh_key_type_to_char(keytype));
  }

  if (strlen(hostkeys) == 0) {
      return -1;
  }

  rc = ssh_options_set_algo(session,
                            SSH_HOSTKEYS,
                            hostkeys[0] == ',' ? hostkeys + 1 : hostkeys);
  if (rc < 0) {
      return -1;
  }

  for (i = 0; i < 10; i++) {
    if ((wanted = session->opts.wanted_methods[i]) == NULL) {
      wanted = ssh_kex_get_supported_method(i);
    }
    server->methods[i] = strdup(wanted);
    if (server->methods[i] == NULL) {
      for (j = 0; j < i; j++) {
        SAFE_FREE(server->methods[j]);
      }
      return -1;
    }
  }

  return 0;
}
コード例 #13
0
ファイル: pki.c プロジェクト: rofl0r/libssh
int ssh_pki_import_pubkey_base64(ssh_session session,
                                 const char *b64_key,
                                 enum ssh_keytypes_e type,
                                 ssh_key *pkey) {
    ssh_buffer buffer;
    ssh_key key;
    int rc;

    key = ssh_key_new();
    if (key == NULL) {
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PUBLIC;

    buffer = base64_to_bin(b64_key);

    switch (type) {
        case SSH_KEYTYPE_DSS:
            {
                ssh_string p;
                ssh_string q;
                ssh_string g;
                ssh_string pubkey;

                p = buffer_get_ssh_string(buffer);
                if (p == NULL) {
                    goto fail;
                }
                q = buffer_get_ssh_string(buffer);
                if (q == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);

                    goto fail;
                }
                g = buffer_get_ssh_string(buffer);
                if (g == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);

                    goto fail;
                }
                pubkey = buffer_get_ssh_string(buffer);
                if (g == NULL) {
                    ssh_string_burn(p);
                    ssh_string_free(p);
                    ssh_string_burn(q);
                    ssh_string_free(q);
                    ssh_string_burn(g);
                    ssh_string_free(g);

                    goto fail;
                }

                rc = pki_pubkey_build_dss(key, p, q, g, pubkey);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("p", ssh_string_data(p), ssh_string_len(p));
                ssh_print_hexa("q", ssh_string_data(q), ssh_string_len(q));
                ssh_print_hexa("g", ssh_string_data(g), ssh_string_len(g));
#endif
                ssh_string_burn(p);
                ssh_string_free(p);
                ssh_string_burn(q);
                ssh_string_free(q);
                ssh_string_burn(g);
                ssh_string_free(g);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_RSA:
        case SSH_KEYTYPE_RSA1:
            {
                ssh_string e;
                ssh_string n;

                e = buffer_get_ssh_string(buffer);
                if (e == NULL) {
                    goto fail;
                }
                n = buffer_get_ssh_string(buffer);
                if (n == NULL) {
                    ssh_string_burn(e);
                    ssh_string_free(e);

                    goto fail;
                }

                rc = pki_pubkey_build_rsa(key, e, n);
#ifdef DEBUG_CRYPTO
                ssh_print_hexa("e", ssh_string_data(e), ssh_string_len(e));
                ssh_print_hexa("n", ssh_string_data(n), ssh_string_len(n));
#endif
                ssh_string_burn(e);
                ssh_string_free(e);
                ssh_string_burn(n);
                ssh_string_free(n);
                if (rc == SSH_ERROR) {
                    goto fail;
                }
            }
            break;
        case SSH_KEYTYPE_ECDSA:
        case SSH_KEYTYPE_UNKNOWN:
            ssh_set_error(session, SSH_FATAL,
                    "Unknown public key protocol %d",
                    type);
            goto fail;
    }

    ssh_buffer_free(buffer);

    *pkey = key;
    return SSH_OK;
fail:
    ssh_buffer_free(buffer);
    ssh_key_free(key);

    return SSH_ERROR;
}
コード例 #14
0
/**
 * @internal
 *
 * @brief Import a private key from a ssh buffer.
 *
 * @param[in] key_blob_buffer The key blob to import as specified in
 *                            key.c:key_private_serialize in OpenSSH source
 *                            code.
 *
 * @param[out] pkey     A pointer where the allocated key can be stored. You
 *                      need to free the memory.
 *
 * @return              SSH_OK on success, SSH_ERROR on error.
 *
 * @see ssh_key_free()
 */
static int pki_openssh_import_privkey_blob(ssh_buffer key_blob_buffer,
                                           ssh_key *pkey)
{
    enum ssh_keytypes_e type;
    char *type_s = NULL;
    ssh_key key = NULL;
    ssh_string pubkey = NULL, privkey = NULL;
    int rc;

    if (pkey == NULL) {
        return SSH_ERROR;
    }

    rc = ssh_buffer_unpack(key_blob_buffer, "s", &type_s);
    if (rc == SSH_ERROR){
        ssh_pki_log("Unpack error");
        return SSH_ERROR;
    }

    type = ssh_key_type_from_name(type_s);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        ssh_pki_log("Unknown key type found!");
        return SSH_ERROR;
    }
    SAFE_FREE(type_s);

    key = ssh_key_new();
    if (key == NULL) {
        ssh_pki_log("Out of memory");
        return SSH_ERROR;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;

    switch (type) {
    case SSH_KEYTYPE_ED25519:
        rc = ssh_buffer_unpack(key_blob_buffer, "SS", &pubkey, &privkey);
        if (rc != SSH_OK){
            ssh_pki_log("Unpack error");
            goto fail;
        }
        if(ssh_string_len(pubkey) != ED25519_PK_LEN ||
                ssh_string_len(privkey) != ED25519_SK_LEN){
            ssh_pki_log("Invalid ed25519 key len");
            goto fail;
        }
        key->ed25519_privkey = malloc(ED25519_SK_LEN);
        key->ed25519_pubkey = malloc(ED25519_PK_LEN);
        if(key->ed25519_privkey == NULL || key->ed25519_pubkey == NULL){
            goto fail;
        }
        memcpy(key->ed25519_privkey, ssh_string_data(privkey), ED25519_SK_LEN);
        memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_PK_LEN);
        memset(ssh_string_data(privkey), 0, ED25519_SK_LEN);
        SAFE_FREE(privkey);
        SAFE_FREE(pubkey);
        break;
    case SSH_KEYTYPE_DSS:
        /* p,q,g,pub_key,priv_key */
    case SSH_KEYTYPE_RSA:
        /* n,e,d,iqmp,p,q */
    case SSH_KEYTYPE_RSA1:
    case SSH_KEYTYPE_ECDSA:
        /* curve_name, group, privkey */
        ssh_pki_log("Unsupported private key method %s", key->type_c);
        goto fail;
    case SSH_KEYTYPE_UNKNOWN:
        ssh_pki_log("Unknown private key protocol %s", key->type_c);
        goto fail;
    }

    *pkey = key;
    return SSH_OK;
fail:
    ssh_key_free(key);
    if(privkey != NULL){
        memset(ssh_string_data(privkey), 0, ssh_string_len(privkey));
    }
    SAFE_FREE(pubkey);
    SAFE_FREE(privkey);

    return SSH_ERROR;
}