Beispiel #1
0
ssh_string make_bignum_string(bignum num) {
  ssh_string ptr = NULL;
  int pad = 0;
  unsigned int len = bignum_num_bytes(num);
  unsigned int bits = bignum_num_bits(num);

  /* Remember if the fist bit is set, it is considered as a
   * negative number. So 0's must be appended */
  if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) {
    pad++;
  }

#ifdef DEBUG_CRYPTO
  fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
#endif /* DEBUG_CRYPTO */
/* TODO: fix that crap !! */
  ptr = malloc(4 + len + pad);
  if (ptr == NULL) {
    return NULL;
  }
  ptr->size = htonl(len + pad);
  if (pad) {
    ptr->string[0] = 0;
  }

#ifdef HAVE_LIBGCRYPT
  bignum_bn2bin(num, len, ptr->string + pad);
#elif HAVE_LIBCRYPTO
  bignum_bn2bin(num, ptr->string + pad);
#endif

  return ptr;
}
Beispiel #2
0
ssh_string ssh_make_bignum_string(bignum num) {
  ssh_string ptr = NULL;
  int pad = 0;
  unsigned int len = bignum_num_bytes(num);
  unsigned int bits = bignum_num_bits(num);

  if (len == 0) {
      return NULL;
  }

  /* If the first bit is set we have a negative number */
  if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) {
    pad++;
  }

#ifdef DEBUG_CRYPTO
  fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
#endif /* DEBUG_CRYPTO */

  ptr = ssh_string_new(len + pad);
  if (ptr == NULL) {
    return NULL;
  }

  /* We have a negative number so we need a leading zero */
  if (pad) {
    ptr->data[0] = 0;
  }

  bignum_bn2bin(num, len, ptr->data + pad);

  return ptr;
}
Beispiel #3
0
/**
 * @brief Check the public key in the known host line matches the public key of
 * the currently connected server.
 *
 * @param[in] session   The SSH session to use.
 *
 * @param[in] tokens    A list of tokens in the known_hosts line.
 *
 * @returns             1 if the key matches, 0 if the key doesn't match and -1
 *                      on error.
 */
static int check_public_key(ssh_session session, char **tokens) {
  ssh_string pubkey = session->current_crypto->server_pubkey;
  ssh_buffer pubkey_buffer;
  char *pubkey_64;

  /* ok we found some public key in known hosts file. now un-base64it */
  if (alldigits(tokens[1])) {
    /* openssh rsa1 format */
    bignum tmpbn;
    ssh_string tmpstring;
    unsigned int len;
    int i;

    pubkey_buffer = ssh_buffer_new();
    if (pubkey_buffer == NULL) {
      return -1;
    }

    tmpstring = ssh_string_from_char("ssh-rsa1");
    if (tmpstring == NULL) {
      ssh_buffer_free(pubkey_buffer);
      return -1;
    }

    if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
      ssh_buffer_free(pubkey_buffer);
      ssh_string_free(tmpstring);
      return -1;
    }
    ssh_string_free(tmpstring);

    for (i = 2; i < 4; i++) { /* e, then n */
      tmpbn = NULL;
      bignum_dec2bn(tokens[i], &tmpbn);
      if (tmpbn == NULL) {
        ssh_buffer_free(pubkey_buffer);
        return -1;
      }
      /* for some reason, make_bignum_string does not work
         because of the padding which it does --kv */
      /* tmpstring = make_bignum_string(tmpbn); */
      /* do it manually instead */
      len = bignum_num_bytes(tmpbn);
      tmpstring = malloc(4 + len);
      if (tmpstring == NULL) {
        ssh_buffer_free(pubkey_buffer);
        bignum_free(tmpbn);
        return -1;
      }
      /* TODO: fix the hardcoding */
      tmpstring->size = htonl(len);
#ifdef HAVE_LIBGCRYPT
      bignum_bn2bin(tmpbn, len, tmpstring->string);
#elif defined HAVE_LIBCRYPTO
      bignum_bn2bin(tmpbn, tmpstring->string);
#endif
      bignum_free(tmpbn);
      if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
        ssh_buffer_free(pubkey_buffer);
        ssh_string_free(tmpstring);
        bignum_free(tmpbn);
        return -1;
      }
      ssh_string_free(tmpstring);
    }
  } else {
    /* ssh-dss or ssh-rsa */
    pubkey_64 = tokens[2];
    pubkey_buffer = base64_to_bin(pubkey_64);
  }

  if (pubkey_buffer == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Verifying that server is a known host: base64 error");
    return -1;
  }

  if (buffer_get_rest_len(pubkey_buffer) != ssh_string_len(pubkey)) {
    ssh_buffer_free(pubkey_buffer);
    return 0;
  }

  /* now test that they are identical */
  if (memcmp(buffer_get_rest(pubkey_buffer), pubkey->string,
        buffer_get_rest_len(pubkey_buffer)) != 0) {
    ssh_buffer_free(pubkey_buffer);
    return 0;
  }

  ssh_buffer_free(pubkey_buffer);
  return 1;
}