Beispiel #1
0
static int build_session_id1(ssh_session session, ssh_string servern,
    ssh_string hostn) {
  MD5CTX md5 = NULL;

  md5 = md5_init();
  if (md5 == NULL) {
    return -1;
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("host modulus",ssh_string_data(hostn),ssh_string_len(hostn));
  ssh_print_hexa("server modulus",ssh_string_data(servern),ssh_string_len(servern));
#endif
  md5_update(md5,ssh_string_data(hostn),ssh_string_len(hostn));
  md5_update(md5,ssh_string_data(servern),ssh_string_len(servern));
  md5_update(md5,session->next_crypto->server_kex.cookie,8);
  if(session->next_crypto->session_id != NULL)
      SAFE_FREE(session->next_crypto->session_id);
  session->next_crypto->session_id = malloc(MD5_DIGEST_LEN);
  if(session->next_crypto->session_id == NULL){
      ssh_set_error_oom(session);
      return SSH_ERROR;
  }
  md5_final(session->next_crypto->session_id,md5);
#ifdef DEBUG_CRYPTO
  ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN);
#endif

  return 0;
}
Beispiel #2
0
static ssh_string make_ecpoint_string(const EC_GROUP *g,
                                      const EC_POINT *p)
{
    ssh_string s;
    size_t len;

    len = EC_POINT_point2oct(g,
                             p,
                             POINT_CONVERSION_UNCOMPRESSED,
                             NULL,
                             0,
                             NULL);
    if (len == 0) {
        return NULL;
    }

    s = ssh_string_new(len);
    if (s == NULL) {
        return NULL;
    }

    len = EC_POINT_point2oct(g,
                             p,
                             POINT_CONVERSION_UNCOMPRESSED,
                             ssh_string_data(s),
                             ssh_string_len(s),
                             NULL);
    if (len != ssh_string_len(s)) {
        ssh_string_free(s);
        return NULL;
    }

    return s;
}
int pki_privkey_build_rsa(ssh_key key,
                          ssh_string n,
                          ssh_string e,
                          ssh_string d,
                          ssh_string iqmp,
                          ssh_string p,
                          ssh_string q)
{
    mbedtls_rsa_context *rsa = NULL;
    const mbedtls_pk_info_t *pk_info = NULL;
    int rc;

    key->rsa = malloc(sizeof(mbedtls_pk_context));
    if (key->rsa == NULL) {
        return SSH_ERROR;
    }

    mbedtls_pk_init(key->rsa);
    pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
    mbedtls_pk_setup(key->rsa, pk_info);

    rc = mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA);
    if (rc == 0) {
        goto fail;
    }

    rsa = mbedtls_pk_rsa(*key->rsa);
    rc = mbedtls_rsa_import_raw(rsa,
                                ssh_string_data(n), ssh_string_len(n),
                                ssh_string_data(p), ssh_string_len(p),
                                ssh_string_data(q), ssh_string_len(q),
                                ssh_string_data(d), ssh_string_len(d),
                                ssh_string_data(e), ssh_string_len(e));
    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARN, "Failed to import private RSA key");
        goto fail;
    }

    rc = mbedtls_rsa_complete(rsa);
    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARN, "Failed to complete private RSA key");
        goto fail;
    }

    rc = mbedtls_rsa_check_privkey(rsa);
    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARN, "Inconsistent private RSA key");
        goto fail;
    }

    return SSH_OK;

fail:
    mbedtls_pk_free(key->rsa);
    SAFE_FREE(key->rsa);
    return SSH_ERROR;
}
static void torture_pubkey_generate_from_privkey(void **state) {
    ssh_session session = *state;
    ssh_private_key privkey = NULL;
    ssh_public_key pubkey = NULL;
    ssh_string pubkey_orig = NULL;
    ssh_string pubkey_new = NULL;
    char pubkey_line_orig[512] = {0};
    char pubkey_line_new[512] = {0};
    int type_orig = 0;
    int type_new = 0;
    int rc;

    /* read the publickey */
    rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey_orig,
        &type_orig);
    assert_true(rc == 0);
    assert_true(pubkey_orig != NULL);

    rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_orig,
        sizeof(pubkey_line_orig));
    assert_true(rc == 0);

    /* remove the public key, generate it from the private key and write it. */
    unlink(LIBSSH_RSA_TESTKEY ".pub");

    privkey = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, NULL);
    assert_true(privkey != NULL);

    pubkey = publickey_from_privatekey(privkey);
    assert_true(pubkey != NULL);
    type_new = privkey->type;
    privatekey_free(privkey);

    pubkey_new = publickey_to_string(pubkey);
    publickey_free(pubkey);

    assert_true(pubkey_new != NULL);

    assert_true(ssh_string_len(pubkey_orig) == ssh_string_len(pubkey_new));
    assert_memory_equal(ssh_string_data(pubkey_orig),
                        ssh_string_data(pubkey_new),
                        ssh_string_len(pubkey_orig));

    rc = ssh_publickey_to_file(session, LIBSSH_RSA_TESTKEY ".pub", pubkey_new, type_new);
    assert_true(rc == 0);

    rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_new,
        sizeof(pubkey_line_new));
    assert_true(rc == 0);

    assert_string_equal(pubkey_line_orig, pubkey_line_new);

    ssh_string_free(pubkey_orig);
    ssh_string_free(pubkey_new);
}
Beispiel #5
0
/** @internal
 * @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
 * a SSH_MSG_NEWKEYS
 */
int ssh_client_curve25519_reply(ssh_session_t * session, ssh_buffer_t * packet){
  ssh_string_t * q_s_string = NULL;
  ssh_string_t * pubkey = NULL;
  ssh_string_t * signature = NULL;
  int rc;
  pubkey = buffer_get_ssh_string(packet);
  if (pubkey == NULL){
    ssh_set_error(session,SSH_FATAL, "No public key in packet");
    goto error;
  }
  /* this is the server host key */
  session->next_crypto->server_pubkey = pubkey;
  pubkey = NULL;

  q_s_string = buffer_get_ssh_string(packet);
  if (q_s_string == NULL) {
	  ssh_set_error(session,SSH_FATAL, "No Q_S ECC point in packet");
	  goto error;
  }
  if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){
	  ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
			  (int)ssh_string_len(q_s_string));
	  ssh_string_free(q_s_string);
	  goto error;
  }
  memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE);
  ssh_string_free(q_s_string);

  signature = buffer_get_ssh_string(packet);
  if (signature == NULL) {
    ssh_set_error(session, SSH_FATAL, "No signature in packet");
    goto error;
  }
  session->next_crypto->dh_server_signature = signature;
  signature=NULL; /* ownership changed */
  /* TODO: verify signature now instead of waiting for NEWKEYS */
  if (ssh_curve25519_build_k(session) < 0) {
    ssh_set_error(session, SSH_FATAL, "Cannot build k number");
    goto error;
  }

  /* Send the MSG_NEWKEYS */
  if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
    goto error;
  }

  rc=packet_send(session);
  SSH_INFO(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
  return rc;
error:
  return SSH_ERROR;
}
Beispiel #6
0
int pki_pubkey_build_rsa(ssh_key key,
                         ssh_string e,
                         ssh_string n) {
    gcry_sexp_build(&key->rsa, NULL,
                    "(public-key(rsa(n %b)(e %b)))",
                    ssh_string_len(n), ssh_string_data(n),
                    ssh_string_len(e),ssh_string_data(e));
    if (key->rsa == NULL) {
        return SSH_ERROR;
    }

    return SSH_OK;
}
Beispiel #7
0
static int ecdh_build_k(ssh_session session) {
  const EC_GROUP *group = EC_KEY_get0_group(session->next_crypto->ecdh_privkey);
  EC_POINT *pubkey;
  void *buffer;
  int len = (EC_GROUP_get_degree(group) + 7) / 8;
  bignum_CTX ctx = bignum_ctx_new();
  if (ctx == NULL) {
    return -1;
  }

  session->next_crypto->k = bignum_new();
  if (session->next_crypto->k == NULL) {
    bignum_ctx_free(ctx);
    return -1;
  }

  pubkey = EC_POINT_new(group);
  if (pubkey == NULL) {
    bignum_ctx_free(ctx);
    return -1;
  }

  if (session->server)
      EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_client_pubkey),
              ssh_string_len(session->next_crypto->ecdh_client_pubkey),ctx);
  else
      EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_server_pubkey),
              ssh_string_len(session->next_crypto->ecdh_server_pubkey),ctx);
  buffer = malloc(len);
  ECDH_compute_key(buffer,len,pubkey,session->next_crypto->ecdh_privkey,NULL);
  EC_POINT_free(pubkey);
  BN_bin2bn(buffer,len,session->next_crypto->k);
  free(buffer);
  EC_KEY_free(session->next_crypto->ecdh_privkey);
  session->next_crypto->ecdh_privkey=NULL;
#ifdef DEBUG_CRYPTO
    ssh_print_hexa("Session server cookie",
                   session->next_crypto->server_kex.cookie, 16);
    ssh_print_hexa("Session client cookie",
                   session->next_crypto->client_kex.cookie, 16);
    ssh_print_bignum("Shared secret key", session->next_crypto->k);
#endif

#ifdef HAVE_LIBCRYPTO
  bignum_ctx_free(ctx);
#endif

  return 0;
}
Beispiel #8
0
/**
 * @deprecated Use ssh_get_publickey_hash()
 */
int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) {
  ssh_string pubkey;
  MD5CTX ctx;
  unsigned char *h;

  if (session == NULL || hash == NULL) {
    return SSH_ERROR;
  }
  *hash = NULL;
  if (session->current_crypto == NULL ||
      session->current_crypto->server_pubkey == NULL){
    ssh_set_error(session,SSH_FATAL,"No current cryptographic context");
    return SSH_ERROR;
  }

  h = malloc(sizeof(unsigned char) * MD5_DIGEST_LEN);
  if (h == NULL) {
    return SSH_ERROR;
  }

  ctx = md5_init();
  if (ctx == NULL) {
    SAFE_FREE(h);
    return SSH_ERROR;
  }

  pubkey = session->current_crypto->server_pubkey;

  md5_update(ctx, ssh_string_data(pubkey), ssh_string_len(pubkey));
  md5_final(h, ctx);

  *hash = h;

  return MD5_DIGEST_LEN;
}
Beispiel #9
0
/**
 * @brief Convert a public key to a base64 encoded key.
 *
 * @param[in] key       The key to hash
 *
 * @param[out] b64_key  A pointer to store the allocated base64 encoded key. You
 *                      need to free the buffer.
 *
 * @return              SSH_OK on success, SSH_ERROR on error.
 *
 * @see ssh_string_free_char()
 */
int ssh_pki_export_pubkey_base64(const ssh_key key,
                                 char **b64_key)
{
    ssh_string key_blob;
    unsigned char *b64;

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

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

    b64 = bin_to_base64(ssh_string_data(key_blob), ssh_string_len(key_blob));
    ssh_string_free(key_blob);
    if (b64 == NULL) {
        return SSH_ERROR;
    }

    *b64_key = (char *)b64;

    return SSH_OK;
}
Beispiel #10
0
int pki_pubkey_build_dss(ssh_key key,
                         ssh_string p,
                         ssh_string q,
                         ssh_string g,
                         ssh_string pubkey) {
    gcry_sexp_build(&key->dsa, NULL,
                    "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",
                    ssh_string_len(p), ssh_string_data(p),
                    ssh_string_len(q), ssh_string_data(q),
                    ssh_string_len(g), ssh_string_data(g),
                    ssh_string_len(pubkey), ssh_string_data(pubkey));
    if (key->dsa == NULL) {
        return SSH_ERROR;
    }

    return SSH_OK;
}
Beispiel #11
0
void make_string_bn_inplace(ssh_string string, bignum bnout) {
  unsigned int len = ssh_string_len(string);
#ifdef HAVE_LIBGCRYPT
  /* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */
  (void) len;
  (void) bnout;
#elif defined HAVE_LIBCRYPTO
  bignum_bin2bn(string->data, len, bnout);
#endif
}
int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n)
{
    mbedtls_rsa_context *rsa = NULL;
    const mbedtls_pk_info_t *pk_info = NULL;
    int rc;

    key->rsa = malloc(sizeof(mbedtls_pk_context));
    if (key->rsa == NULL) {
        return SSH_ERROR;
    }

    mbedtls_pk_init(key->rsa);
    pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
    mbedtls_pk_setup(key->rsa, pk_info);

    rc = mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA);
    if (rc == 0) {
        goto fail;
    }

    rsa = mbedtls_pk_rsa(*key->rsa);
    rc = mbedtls_mpi_read_binary(&rsa->N, ssh_string_data(n),
                                 ssh_string_len(n));
    if (rc != 0) {
        goto fail;
    }
    rc = mbedtls_mpi_read_binary(&rsa->E, ssh_string_data(e),
                                 ssh_string_len(e));
    if (rc != 0) {
        goto fail;
    }

    rsa->len = (mbedtls_mpi_bitlen(&rsa->N) + 7) >> 3;

    return SSH_OK;

fail:
    mbedtls_pk_free(key->rsa);
    SAFE_FREE(key->rsa);
    return SSH_ERROR;
}
Beispiel #13
0
/**
 * @internal
 *
 * @brief Import a public key from a ssh string.
 *
 * @param[in]  key_blob The key blob to import as specified in RFC 4253 section
 *                      6.6 "Public Key Algorithms".
 *
 * @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()
 */
int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
                               ssh_key *pkey) {
    ssh_buffer buffer;
    ssh_string type_s = NULL;
    enum ssh_keytypes_e type;
    int rc;

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

    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        SSH_LOG(SSH_LOG_WARN, "Out of memory!");
        return SSH_ERROR;
    }

    rc = ssh_buffer_add_data(buffer, ssh_string_data(key_blob),
            ssh_string_len(key_blob));
    if (rc < 0) {
        SSH_LOG(SSH_LOG_WARN, "Out of memory!");
        goto fail;
    }

    type_s = ssh_buffer_get_ssh_string(buffer);
    if (type_s == NULL) {
        SSH_LOG(SSH_LOG_WARN, "Out of memory!");
        goto fail;
    }

    type = ssh_key_type_from_name(ssh_string_get_char(type_s));
    if (type == SSH_KEYTYPE_UNKNOWN) {
        SSH_LOG(SSH_LOG_WARN, "Unknown key type found!");
        goto fail;
    }
    ssh_string_free(type_s);

    if (type == SSH_KEYTYPE_RSA_CERT01 ||
        type == SSH_KEYTYPE_DSS_CERT01) {
        rc = pki_import_cert_buffer(buffer, type, pkey);
    } else {
        rc = pki_import_pubkey_buffer(buffer, type, pkey);
    }

    ssh_buffer_free(buffer);

    return rc;
fail:
    ssh_buffer_free(buffer);
    ssh_string_free(type_s);

    return SSH_ERROR;
}
Beispiel #14
0
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
                                  const ssh_key pubkey,
                                  ssh_signature *psig)
{
    ssh_signature sig;
    enum ssh_keytypes_e type;
    ssh_string str;
    ssh_buffer buf;
    int rc;

    if (sig_blob == NULL || psig == NULL) {
        return SSH_ERROR;
    }

    buf = ssh_buffer_new();
    if (buf == NULL) {
        return SSH_ERROR;
    }

    rc = ssh_buffer_add_data(buf,
                             ssh_string_data(sig_blob),
                             ssh_string_len(sig_blob));
    if (rc < 0) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    str = ssh_buffer_get_ssh_string(buf);
    if (str == NULL) {
        ssh_buffer_free(buf);
        return SSH_ERROR;
    }

    type = ssh_key_type_from_name(ssh_string_get_char(str));
    ssh_string_free(str);

    str = ssh_buffer_get_ssh_string(buf);
    ssh_buffer_free(buf);
    if (str == NULL) {
        return SSH_ERROR;
    }

    sig = pki_signature_from_blob(pubkey, str, type);
    ssh_string_free(str);
    if (sig == NULL) {
        return SSH_ERROR;
    }

    *psig = sig;
    return SSH_OK;
}
Beispiel #15
0
static int generate_one_key(ssh_string k,
    struct ssh_crypto_struct *crypto, unsigned char **output, char letter, size_t requested_size) {
  ssh_mac_ctx ctx;
  unsigned char *tmp;
  size_t size = crypto->digest_len;
  ctx=ssh_mac_ctx_init(crypto->mac_type);

  if (ctx == NULL) {
    return -1;
  }

  ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
  ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
  ssh_mac_update(ctx, &letter, 1);
  ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
  ssh_mac_final(*output, ctx);

  while(requested_size > size) {
    tmp = realloc(*output, size + crypto->digest_len);
    if (tmp == NULL) {
      return -1;
    }
    *output = tmp;

    ctx = ssh_mac_ctx_init(crypto->mac_type);
    if (ctx == NULL) {
      return -1;
    }
    ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
    ssh_mac_update(ctx, crypto->secret_hash,
        crypto->digest_len);
    ssh_mac_update(ctx, tmp, size);
    ssh_mac_final(tmp + size, ctx);
    size += crypto->digest_len;
  }

  return 0;
}
Beispiel #16
0
bignum ssh_make_string_bn(ssh_string string)
{
    bignum bn = NULL;
    size_t len = ssh_string_len(string);

#ifdef DEBUG_CRYPTO
    fprintf(stderr, "Importing a %zu bits, %zu bytes object ...\n",
            len * 8, len);
#endif /* DEBUG_CRYPTO */

    bignum_bin2bn(string->data, len, &bn);

    return bn;
}
Beispiel #17
0
/**
 * @brief Export a private key to a pem file on disk, or OpenSSH format for
 *        keytype ssh-ed25519
 *
 * @param[in]  privkey  The private key to export.
 *
 * @param[in]  passphrase The passphrase to use to encrypt the key with or
 *             NULL. An empty string means no passphrase.
 *
 * @param[in]  auth_fn  An auth function you may want to use or NULL.
 *
 * @param[in]  auth_data Private data passed to the auth function.
 *
 * @param[in]  filename  The path where to store the pem file.
 *
 * @return     SSH_OK on success, SSH_ERROR on error.
 */
int ssh_pki_export_privkey_file(const ssh_key privkey,
                                const char *passphrase,
                                ssh_auth_callback auth_fn,
                                void *auth_data,
                                const char *filename)
{
    ssh_string blob;
    FILE *fp;
    int rc;

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

    fp = fopen(filename, "wb");
    if (fp == NULL) {
        SSH_LOG(SSH_LOG_FUNCTIONS, "Error opening %s: %s",
                filename, strerror(errno));
        return SSH_EOF;
    }

    if (privkey->type == SSH_KEYTYPE_ED25519){
        blob = ssh_pki_openssh_privkey_export(privkey,
                                              passphrase,
                                              auth_fn,
                                              auth_data);
    } else {
        blob = pki_private_key_to_pem(privkey,
                                      passphrase,
                                      auth_fn,
                                      auth_data);
    }
    if (blob == NULL) {
        fclose(fp);
        return -1;
    }

    rc = fwrite(ssh_string_data(blob), ssh_string_len(blob), 1, fp);
    ssh_string_free(blob);
    if (rc != 1 || ferror(fp)) {
        fclose(fp);
        unlink(filename);
        return SSH_ERROR;
    }
    fclose(fp);

    return SSH_OK;
}
Beispiel #18
0
bignum make_string_bn(ssh_string string){
  bignum bn = NULL;
  unsigned int len = ssh_string_len(string);

#ifdef DEBUG_CRYPTO
  fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
      len * 8, len);
#endif /* DEBUG_CRYPTO */

#ifdef HAVE_LIBGCRYPT
  bignum_bin2bn(string->data, len, &bn);
#elif defined HAVE_LIBCRYPTO
  bn = bignum_bin2bn(string->data, len, NULL);
#endif

  return bn;
}
Beispiel #19
0
/*
 * This function signs the session id (known as H) as a string then
 * the content of sigbuf */
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
    ssh_key privatekey) {
    struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto :
        session->next_crypto;
    unsigned char hash[SHA_DIGEST_LEN + 1] = {0};
    ssh_string session_str = NULL;
    ssh_string signature = NULL;
    struct signature_struct *sign = NULL;
    SHACTX ctx = NULL;

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

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

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

    sha1_update(ctx, session_str, ssh_string_len(session_str) + 4);
    ssh_string_free(session_str);
    sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
    sha1_final(hash + 1,ctx);
    hash[0] = 0;

#ifdef DEBUG_CRYPTO
    ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN);
#endif

    sign = pki_do_sign(privatekey, hash);
    if (sign == NULL) {
        return NULL;
    }

    signature = signature_to_string(sign);
    signature_free(sign);

    return signature;
}
Beispiel #20
0
static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s){
    gss_OID ret = malloc(sizeof (gss_OID_desc));
    unsigned char *data = ssh_string_data(oid_s);
    size_t len = ssh_string_len(oid_s);
    if(len > 256 || len <= 2){
        SAFE_FREE(ret);
        return NULL;
    }
    if(data[0] != SSH_OID_TAG || data[1] != len - 2){
        SAFE_FREE(ret);
        return NULL;
    }
    ret->elements = malloc(len - 2);
    memcpy(ret->elements, &data[2], len-2);
    ret->length = len-2;
    return ret;
}
Beispiel #21
0
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
    ssh_buffer tmpbuf = NULL;
    ssh_string type_s = NULL;
    char *type_c = NULL;
    int type;

    tmpbuf = ssh_buffer_new();
    if (tmpbuf == NULL) {
        return NULL;
    }

    if (buffer_add_data(tmpbuf, ssh_string_data(pubkey_s), ssh_string_len(pubkey_s)) < 0) {
        goto error;
    }

    type_s = buffer_get_ssh_string(tmpbuf);
    if (type_s == NULL) {
        ssh_set_error(session,SSH_FATAL,"Invalid public key format");
        goto error;
    }

    type_c = ssh_string_to_char(type_s);
    ssh_string_free(type_s);
    if (type_c == NULL) {
        goto error;
    }

    type = ssh_type_from_name(type_c);
    SAFE_FREE(type_c);

    switch (type) {
    case SSH_KEYTYPE_DSS:
        return publickey_make_dss(session, tmpbuf);
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
        return publickey_make_rsa(session, tmpbuf, type);
    }

    ssh_set_error(session, SSH_FATAL, "Unknown public key protocol %s",
                  ssh_type_to_char(type));

error:
    ssh_buffer_free(tmpbuf);
    return NULL;
}
Beispiel #22
0
void *sftp_handle(sftp_session sftp, ssh_string handle){
  uint32_t val;

  if (sftp->handles == NULL) {
    return NULL;
  }

  if (ssh_string_len(handle) != sizeof(uint32_t)) {
    return NULL;
  }

  memcpy(&val, ssh_string_data(handle), sizeof(uint32_t));

  if (val > SFTP_HANDLES) {
    return NULL;
  }

  return sftp->handles[val];
}
Beispiel #23
0
static int generate_one_key(ssh_string k,
    unsigned char session_id[SHA_DIGEST_LEN],
    unsigned char output[SHA_DIGEST_LEN],
    char letter) {
  SHACTX ctx = NULL;

  ctx = sha1_init();
  if (ctx == NULL) {
    return -1;
  }

  sha1_update(ctx, k, ssh_string_len(k) + 4);
  sha1_update(ctx, session_id, SHA_DIGEST_LEN);
  sha1_update(ctx, &letter, 1);
  sha1_update(ctx, session_id, SHA_DIGEST_LEN);
  sha1_final(output, ctx);

  return 0;
}
Beispiel #24
0
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
{
    EC_POINT *p;
    const EC_GROUP *g;
    int ok;

    key->ecdsa_nid = nid;
    key->type_c = pki_key_ecdsa_nid_to_name(nid);

    key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
    if (key->ecdsa == NULL) {
        return -1;
    }

    g = EC_KEY_get0_group(key->ecdsa);

    p = EC_POINT_new(g);
    if (p == NULL) {
        return -1;
    }

    ok = EC_POINT_oct2point(g,
                            p,
                            ssh_string_data(e),
                            ssh_string_len(e),
                            NULL);
    if (!ok) {
        EC_POINT_free(p);
        return -1;
    }

    /* EC_KEY_set_public_key duplicates p */
    ok = EC_KEY_set_public_key(key->ecdsa, p);
    EC_POINT_free(p);
    if (!ok) {
        return -1;
    }

    return 0;
}
Beispiel #25
0
/* TODO : split this function in two so it becomes smaller */
SIGNATURE *signature_from_string(ssh_session session, ssh_string signature,
                                 ssh_public_key pubkey, int needed_type) {
    SIGNATURE *sign = NULL;
    ssh_buffer tmpbuf = NULL;
    ssh_string rs = NULL;
    ssh_string type_s = NULL;
    ssh_string e = NULL;
    char *type_c = NULL;
    int type;
    int len;
    int rsalen;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sig;
#elif defined HAVE_LIBCRYPTO
    DSA_SIG *sig = NULL;
    ssh_string r = NULL;
    ssh_string s = NULL;
#endif

    sign = malloc(sizeof(SIGNATURE));
    if (sign == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        return NULL;
    }
    ZERO_STRUCTP(sign);

    tmpbuf = ssh_buffer_new();
    if (tmpbuf == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        signature_free(sign);
        return NULL;
    }

    if (buffer_add_data(tmpbuf, ssh_string_data(signature), ssh_string_len(signature)) < 0) {
        signature_free(sign);
        ssh_buffer_free(tmpbuf);
        return NULL;
    }

    type_s = buffer_get_ssh_string(tmpbuf);
    if (type_s == NULL) {
        ssh_set_error(session, SSH_FATAL, "Invalid signature packet");
        signature_free(sign);
        ssh_buffer_free(tmpbuf);
        return NULL;
    }

    type_c = ssh_string_to_char(type_s);
    ssh_string_free(type_s);
    if (type_c == NULL) {
        signature_free(sign);
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    type = ssh_type_from_name(type_c);
    SAFE_FREE(type_c);

    if (needed_type != type) {
        ssh_set_error(session, SSH_FATAL, "Invalid signature type: %s",
                      ssh_type_to_char(type));
        signature_free(sign);
        ssh_buffer_free(tmpbuf);
        return NULL;
    }

    switch(needed_type) {
    case SSH_KEYTYPE_DSS:
        rs = buffer_get_ssh_string(tmpbuf);
        ssh_buffer_free(tmpbuf);

        /* 40 is the dual signature blob len. */
        if (rs == NULL || ssh_string_len(rs) != 40) {
            ssh_string_free(rs);
            signature_free(sign);
            return NULL;
        }

        /* we make use of strings (because we have all-made functions to convert
         * them to bignums (ou pas ;) */
#ifdef HAVE_LIBGCRYPT
        if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
                            20 ,ssh_string_data(rs), 20,(unsigned char *)ssh_string_data(rs) + 20)) {
            ssh_string_free(rs);
            signature_free(sign);
            return NULL;
        }
#elif defined HAVE_LIBCRYPTO
        r = ssh_string_new(20);
        s = ssh_string_new(20);
        if (r == NULL || s == NULL) {
            ssh_string_free(r);
            ssh_string_free(s);
            ssh_string_free(rs);
            signature_free(sign);
            return NULL;
        }

        ssh_string_fill(r, ssh_string_data(rs), 20);
        ssh_string_fill(s, (char *)ssh_string_data(rs) + 20, 20);

        sig = DSA_SIG_new();
        if (sig == NULL) {
            ssh_string_free(r);
            ssh_string_free(s);
            ssh_string_free(rs);
            signature_free(sign);
            return NULL;
        }
        sig->r = make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
        sig->s = make_string_bn(s);
        ssh_string_free(r);
        ssh_string_free(s);

        if (sig->r == NULL || sig->s == NULL) {
            ssh_string_free(rs);
            DSA_SIG_free(sig);
            signature_free(sign);
            return NULL;
        }
#endif

#ifdef DEBUG_CRYPTO
        ssh_print_hexa("r", ssh_string_data(rs), 20);
        ssh_print_hexa("s", (const unsigned char *)ssh_string_data(rs) + 20, 20);
#endif
        ssh_string_free(rs);

        sign->type = SSH_KEYTYPE_DSS;
        sign->dsa_sign = sig;

        return sign;
    case SSH_KEYTYPE_RSA:
        e = buffer_get_ssh_string(tmpbuf);
        ssh_buffer_free(tmpbuf);
        if (e == NULL) {
            signature_free(sign);
            return NULL;
        }
        len = ssh_string_len(e);
#ifdef HAVE_LIBGCRYPT
        rsalen = (gcry_pk_get_nbits(pubkey->rsa_pub) + 7) / 8;
#elif defined HAVE_LIBCRYPTO
        rsalen = RSA_size(pubkey->rsa_pub);
#endif
        if (len > rsalen) {
            ssh_string_free(e);
            signature_free(sign);
            ssh_set_error(session, SSH_FATAL, "Signature too big! %d instead of %d",
                          len, rsalen);
            return NULL;
        }

        if (len < rsalen) {
            ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d",
                    len, rsalen);
        }
        sign->type = SSH_KEYTYPE_RSA;
#ifdef HAVE_LIBGCRYPT
        if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
                            ssh_string_len(e), ssh_string_data(e))) {
            signature_free(sign);
            ssh_string_free(e);
            return NULL;
        }

        sign->rsa_sign = sig;
#elif defined HAVE_LIBCRYPTO
        sign->rsa_sign = e;
#endif

#ifdef DEBUG_CRYPTO
        ssh_log(session, SSH_LOG_FUNCTIONS, "len e: %d", len);
        ssh_print_hexa("RSA signature", ssh_string_data(e), len);
#endif

#ifdef HAVE_LIBGCRYPT
        ssh_string_free(e);
#endif

        return sign;
    default:
        return NULL;
    }

    return NULL;
}
Beispiel #26
0
ssh_public_key publickey_make_dss(ssh_session session, ssh_buffer buffer) {
    ssh_string p = NULL;
    ssh_string q = NULL;
    ssh_string g = NULL;
    ssh_string pubkey = NULL;
    ssh_public_key key = NULL;

    key = malloc(sizeof(struct ssh_public_key_struct));
    if (key == NULL) {
        ssh_buffer_free(buffer);
        return NULL;
    }

    ZERO_STRUCTP(key);

    key->type = SSH_KEYTYPE_DSS;
    key->type_c = ssh_type_to_char(key->type);

    p = buffer_get_ssh_string(buffer);
    q = buffer_get_ssh_string(buffer);
    g = buffer_get_ssh_string(buffer);
    pubkey = buffer_get_ssh_string(buffer);

    ssh_buffer_free(buffer); /* we don't need it anymore */

    if (p == NULL || q == NULL || g == NULL || pubkey == NULL) {
        ssh_set_error(session, SSH_FATAL, "Invalid DSA public key");
        goto error;
    }

#ifdef HAVE_LIBGCRYPT
    gcry_sexp_build(&key->dsa_pub, NULL,
                    "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",
                    ssh_string_len(p), ssh_string_data(p),
                    ssh_string_len(q), ssh_string_data(q),
                    ssh_string_len(g), ssh_string_data(g),
                    ssh_string_len(pubkey), ssh_string_data(pubkey));
    if (key->dsa_pub == NULL) {
        goto error;
    }
#elif defined HAVE_LIBCRYPTO

    key->dsa_pub = DSA_new();
    if (key->dsa_pub == NULL) {
        goto error;
    }
    key->dsa_pub->p = make_string_bn(p);
    key->dsa_pub->q = make_string_bn(q);
    key->dsa_pub->g = make_string_bn(g);
    key->dsa_pub->pub_key = make_string_bn(pubkey);
    if (key->dsa_pub->p == NULL ||
            key->dsa_pub->q == NULL ||
            key->dsa_pub->g == NULL ||
            key->dsa_pub->pub_key == NULL) {
        goto error;
    }
#endif /* HAVE_LIBCRYPTO */

#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);

    return key;
error:
    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);
    publickey_free(key);

    return NULL;
}
Beispiel #27
0
/* Signature decoding functions */
ssh_string signature_to_string(SIGNATURE *sign) {
    unsigned char buffer[40] = {0};
    ssh_buffer tmpbuf = NULL;
    ssh_string str = NULL;
    ssh_string tmp = NULL;
    ssh_string rs = NULL;
    int rc = -1;
#ifdef HAVE_LIBGCRYPT
    const char *r = NULL;
    const char *s = NULL;
    gcry_sexp_t sexp;
    size_t size = 0;
#elif defined HAVE_LIBCRYPTO
    ssh_string r = NULL;
    ssh_string s = NULL;
#endif

    tmpbuf = ssh_buffer_new();
    if (tmpbuf == NULL) {
        return NULL;
    }

    tmp = ssh_string_from_char(ssh_type_to_char(sign->type));
    if (tmp == NULL) {
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    if (buffer_add_ssh_string(tmpbuf, tmp) < 0) {
        ssh_buffer_free(tmpbuf);
        ssh_string_free(tmp);
        return NULL;
    }
    ssh_string_free(tmp);

    switch(sign->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        r = gcry_sexp_nth_data(sexp, 1, &size);
        if (*r == 0) {      /* libgcrypt put 0 when first bit is set */
            size--;
            r++;
        }
        memcpy(buffer, r + size - 20, 20);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(sign->dsa_sign, "s", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = gcry_sexp_nth_data(sexp,1,&size);
        if (*s == 0) {
            size--;
            s++;
        }
        memcpy(buffer+ 20, s + size - 20, 20);
        gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
        r = make_bignum_string(sign->dsa_sign->r);
        if (r == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = make_bignum_string(sign->dsa_sign->s);
        if (s == NULL) {
            ssh_buffer_free(tmpbuf);
            ssh_string_free(r);
            return NULL;
        }

        memcpy(buffer, (char *)ssh_string_data(r) + ssh_string_len(r) - 20, 20);
        memcpy(buffer + 20, (char *)ssh_string_data(s) + ssh_string_len(s) - 20, 20);

        ssh_string_free(r);
        ssh_string_free(s);
#endif /* HAVE_LIBCRYPTO */
        rs = ssh_string_new(40);
        if (rs == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        ssh_string_fill(rs, buffer, 40);
        rc = buffer_add_ssh_string(tmpbuf, rs);
        ssh_string_free(rs);
        if (rc < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(sign->rsa_sign, "s", 0);
        if (sexp == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
        s = gcry_sexp_nth_data(sexp,1,&size);
        if (*s == 0) {
            size--;
            s++;
        }
        rs = ssh_string_new(size);
        if (rs == NULL) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }

        ssh_string_fill(rs, (char *) s, size);
        rc = buffer_add_ssh_string(tmpbuf, rs);
        gcry_sexp_release(sexp);
        ssh_string_free(rs);
        if (rc < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
#elif defined HAVE_LIBCRYPTO
        if (buffer_add_ssh_string(tmpbuf,sign->rsa_sign) < 0) {
            ssh_buffer_free(tmpbuf);
            return NULL;
        }
#endif
        break;
    }

    str = ssh_string_new(buffer_get_rest_len(tmpbuf));
    if (str == NULL) {
        ssh_buffer_free(tmpbuf);
        return NULL;
    }
    ssh_string_fill(str, buffer_get_rest(tmpbuf), buffer_get_rest_len(tmpbuf));
    ssh_buffer_free(tmpbuf);

    return str;
}
Beispiel #28
0
/**
 * @brief Make a public_key object out of a private_key object.
 *
 * @param[in]  prv      The private key to generate the public key.
 *
 * @returns             The generated public key, NULL on error.
 *
 * @see publickey_to_string()
 */
ssh_public_key publickey_from_privatekey(ssh_private_key prv) {
    ssh_public_key key = NULL;
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
    const char *tmp = NULL;
    size_t size;
    ssh_string p = NULL;
    ssh_string q = NULL;
    ssh_string g = NULL;
    ssh_string y = NULL;
    ssh_string e = NULL;
    ssh_string n = NULL;
#endif /* HAVE_LIBGCRYPT */

    key = malloc(sizeof(struct ssh_public_key_struct));
    if (key == NULL) {
        return NULL;
    }
    ZERO_STRUCTP(key);
    key->type = prv->type;
    switch(key->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(prv->dsa_priv, "p", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp, 1, &size);
        p = ssh_string_new(size);
        if (p == NULL) {
            goto error;
        }
        ssh_string_fill(p,(char *) tmp, size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->dsa_priv,"q",0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp,1,&size);
        q = ssh_string_new(size);
        if (q == NULL) {
            goto error;
        }
        ssh_string_fill(q,(char *) tmp,size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->dsa_priv, "g", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp,1,&size);
        g = ssh_string_new(size);
        if (g == NULL) {
            goto error;
        }
        ssh_string_fill(g,(char *) tmp,size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->dsa_priv,"y",0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp,1,&size);
        y = ssh_string_new(size);
        if (y == NULL) {
            goto error;
        }
        ssh_string_fill(y,(char *) tmp,size);
        gcry_sexp_release(sexp);

        gcry_sexp_build(&key->dsa_pub, NULL,
                        "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",
                        ssh_string_len(p), ssh_string_data(p),
                        ssh_string_len(q), ssh_string_data(q),
                        ssh_string_len(g), ssh_string_data(g),
                        ssh_string_len(y), ssh_string_data(y));

        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(y);
        ssh_string_free(y);
#elif defined HAVE_LIBCRYPTO
        key->dsa_pub = DSA_new();
        if (key->dsa_pub == NULL) {
            goto error;
        }
        key->dsa_pub->p = BN_dup(prv->dsa_priv->p);
        key->dsa_pub->q = BN_dup(prv->dsa_priv->q);
        key->dsa_pub->g = BN_dup(prv->dsa_priv->g);
        key->dsa_pub->pub_key = BN_dup(prv->dsa_priv->pub_key);
        if (key->dsa_pub->p == NULL ||
                key->dsa_pub->q == NULL ||
                key->dsa_pub->g == NULL ||
                key->dsa_pub->pub_key == NULL) {
            goto error;
        }
#endif /* HAVE_LIBCRYPTO */
        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
        sexp = gcry_sexp_find_token(prv->rsa_priv, "n", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp, 1, &size);
        n = ssh_string_new(size);
        if (n == NULL) {
            goto error;
        }
        ssh_string_fill(n, (char *) tmp, size);
        gcry_sexp_release(sexp);

        sexp = gcry_sexp_find_token(prv->rsa_priv, "e", 0);
        if (sexp == NULL) {
            goto error;
        }
        tmp = gcry_sexp_nth_data(sexp, 1, &size);
        e = ssh_string_new(size);
        if (e == NULL) {
            goto error;
        }
        ssh_string_fill(e, (char *) tmp, size);
        gcry_sexp_release(sexp);

        gcry_sexp_build(&key->rsa_pub, NULL,
                        "(public-key(rsa(n %b)(e %b)))",
                        ssh_string_len(n), ssh_string_data(n),
                        ssh_string_len(e), ssh_string_data(e));
        if (key->rsa_pub == NULL) {
            goto error;
        }

        ssh_string_burn(e);
        ssh_string_free(e);
        ssh_string_burn(n);
        ssh_string_free(n);
#elif defined HAVE_LIBCRYPTO
        key->rsa_pub = RSA_new();
        if (key->rsa_pub == NULL) {
            goto error;
        }
        key->rsa_pub->e = BN_dup(prv->rsa_priv->e);
        key->rsa_pub->n = BN_dup(prv->rsa_priv->n);
        if (key->rsa_pub->e == NULL ||
                key->rsa_pub->n == NULL) {
            goto error;
        }
#endif
        break;
    default:
        publickey_free(key);
        return NULL;
    }
    key->type_c = ssh_type_to_char(prv->type);

    return key;
error:
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(sexp);
    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(y);
    ssh_string_free(y);

    ssh_string_burn(e);
    ssh_string_free(e);
    ssh_string_burn(n);
    ssh_string_free(n);
#endif
    publickey_free(key);

    return NULL;
}
Beispiel #29
0
ssh_public_key publickey_make_rsa(ssh_session session, ssh_buffer buffer,
                                  int type) {
    ssh_string e = NULL;
    ssh_string n = NULL;
    ssh_public_key key = NULL;

    key = malloc(sizeof(struct ssh_public_key_struct));
    if (key == NULL) {
        ssh_buffer_free(buffer);
        return NULL;
    }
    ZERO_STRUCTP(key);

    key->type = type;
    key->type_c = ssh_type_to_char(key->type);

    e = buffer_get_ssh_string(buffer);
    n = buffer_get_ssh_string(buffer);

    ssh_buffer_free(buffer); /* we don't need it anymore */

    if(e == NULL || n == NULL) {
        ssh_set_error(session, SSH_FATAL, "Invalid RSA public key");
        goto error;
    }
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_build(&key->rsa_pub, NULL,
                    "(public-key(rsa(n %b)(e %b)))",
                    ssh_string_len(n), ssh_string_data(n),
                    ssh_string_len(e),ssh_string_data(e));
    if (key->rsa_pub == NULL) {
        goto error;
    }
#elif HAVE_LIBCRYPTO
    key->rsa_pub = RSA_new();
    if (key->rsa_pub == NULL) {
        goto error;
    }

    key->rsa_pub->e = make_string_bn(e);
    key->rsa_pub->n = make_string_bn(n);
    if (key->rsa_pub->e == NULL ||
            key->rsa_pub->n == NULL) {
        goto error;
    }
#endif

#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);

    return key;
error:
    ssh_string_burn(e);
    ssh_string_free(e);
    ssh_string_burn(n);
    ssh_string_free(n);
    publickey_free(key);

    return NULL;
}
Beispiel #30
0
ssh_string ssh_encrypt_rsa1(ssh_session session, ssh_string data, ssh_public_key key) {
    ssh_string str = NULL;
    size_t len = ssh_string_len(data);
    size_t size = 0;
#ifdef HAVE_LIBGCRYPT
    const char *tmp = NULL;
    gcry_sexp_t ret_sexp;
    gcry_sexp_t data_sexp;

    if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))",
                        len, ssh_string_data(data))) {
        ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
        return NULL;
    }
    if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) {
        gcry_sexp_release(data_sexp);
        ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
        return NULL;
    }

    gcry_sexp_release(data_sexp);

    data_sexp = gcry_sexp_find_token(ret_sexp, "a", 0);
    if (data_sexp == NULL) {
        ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
        gcry_sexp_release(ret_sexp);
        return NULL;
    }
    tmp = gcry_sexp_nth_data(data_sexp, 1, &size);
    if (*tmp == 0) {
        size--;
        tmp++;
    }

    str = ssh_string_new(size);
    if (str == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        gcry_sexp_release(data_sexp);
        gcry_sexp_release(ret_sexp);
        return NULL;
    }
    ssh_string_fill(str, tmp, size);

    gcry_sexp_release(data_sexp);
    gcry_sexp_release(ret_sexp);
#elif defined HAVE_LIBCRYPTO
    size = RSA_size(key->rsa_pub);

    str = ssh_string_new(size);
    if (str == NULL) {
        ssh_set_error(session, SSH_FATAL, "Not enough space");
        return NULL;
    }

    if (RSA_public_encrypt(len, ssh_string_data(data), ssh_string_data(str), key->rsa_pub,
                           RSA_PKCS1_PADDING) < 0) {
        ssh_string_free(str);
        return NULL;
    }
#endif

    return str;
}