Esempio n. 1
0
File: dh.c Progetto: mwgoldsmith/ssh
/** @internal
 * @brief Starts diffie-hellman-group1 key exchange
 */
int ssh_client_dh_init(ssh_session session){
  ssh_string e = NULL;
  int rc;

  if (dh_generate_x(session) < 0) {
    goto error;
  }
  if (dh_generate_e(session) < 0) {
    goto error;
  }

  e = dh_get_e(session);
  if (e == NULL) {
    goto error;
  }

  rc = ssh_buffer_pack(session->out_buffer, "bS", SSH2_MSG_KEXDH_INIT, e);
  if (rc != SSH_OK) {
    goto error;
  }

  ssh_string_burn(e);
  ssh_string_free(e);
  e=NULL;

  rc = packet_send(session);
  return rc;
  error:
  if(e != NULL){
    ssh_string_burn(e);
    ssh_string_free(e);
  }

  return SSH_ERROR;
}
Esempio n. 2
0
File: dh.c Progetto: mwgoldsmith/ssh
int ssh_client_dh_reply(ssh_session session, ssh_buffer packet){
  ssh_string f;
  ssh_string pubkey = NULL;
  ssh_string 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;
  }
  dh_import_pubkey(session, pubkey);

  f = buffer_get_ssh_string(packet);
  if (f == NULL) {
    ssh_set_error(session,SSH_FATAL, "No F number in packet");
    goto error;
  }
  rc = dh_import_f(session, f);
  ssh_string_burn(f);
  ssh_string_free(f);
  if (rc < 0) {
    ssh_set_error(session, SSH_FATAL, "Cannot import f number");
    goto error;
  }

  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 */
  if (dh_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_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
  return rc;
error:
  return SSH_ERROR;
}
Esempio n. 3
0
/*
 * Extract an MPI from the given s-expression SEXP named NAME which is
 * encoded using INFORMAT and store it in a newly allocated ssh_string
 * encoded using OUTFORMAT.
 */
ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
                                const char *name,
                                enum gcry_mpi_format informat,
                                enum gcry_mpi_format outformat)
{
    gpg_error_t err;
    ssh_string result = NULL;
    gcry_sexp_t fragment = NULL;
    gcry_mpi_t mpi = NULL;
    size_t size;

    fragment = gcry_sexp_find_token(sexp, name, 0);
    if (fragment == NULL) {
        goto fail;
    }

    mpi = gcry_sexp_nth_mpi(fragment, 1, informat);
    if (mpi == NULL) {
        goto fail;
    }

    err = gcry_mpi_print(outformat, NULL, 0, &size, mpi);
    if (err != 0) {
        goto fail;
    }

    result = ssh_string_new(size);
    if (result == NULL) {
        goto fail;
    }

    err = gcry_mpi_print(outformat, ssh_string_data(result), size, NULL, mpi);
    if (err != 0) {
        ssh_string_burn(result);
        ssh_string_free(result);
        result = NULL;
        goto fail;
    }

fail:
    gcry_sexp_release(fragment);
    gcry_mpi_release(mpi);
    return result;
}
Esempio n. 4
0
File: keys.c Progetto: rofl0r/libssh
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;
}
Esempio n. 5
0
File: keys.c Progetto: rofl0r/libssh
static int rsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) {
#elif defined HAVE_LIBCRYPTO
static int rsa_public_to_string(RSA *key, ssh_buffer buffer) {
#endif

    ssh_string e = NULL;
    ssh_string n = NULL;

    int rc = -1;

#ifdef HAVE_LIBGCRYPT
    const char *tmp;
    size_t size;
    gcry_sexp_t sexp;

    sexp = gcry_sexp_find_token(key, "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(key, "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);

#elif defined HAVE_LIBCRYPTO
    e = make_bignum_string(key->e);
    n = make_bignum_string(key->n);
    if (e == NULL || n == NULL) {
        goto error;
    }
#endif

    if (buffer_add_ssh_string(buffer, e) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, n) < 0) {
        goto error;
    }

    rc = 0;
error:
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(sexp);
#endif

    ssh_string_burn(e);
    ssh_string_free(e);
    ssh_string_burn(n);
    ssh_string_free(n);

    return rc;
#if defined(HAVE_LIBGCRYPT) || defined(HAVE_LIBCRYPTO)
}
Esempio n. 6
0
File: keys.c Progetto: rofl0r/libssh
static int dsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) {
#elif defined HAVE_LIBCRYPTO
static int dsa_public_to_string(DSA *key, ssh_buffer buffer) {
#endif
    ssh_string p = NULL;
    ssh_string q = NULL;
    ssh_string g = NULL;
    ssh_string n = NULL;

    int rc = -1;

#ifdef HAVE_LIBGCRYPT
    const char *tmp = NULL;
    size_t size;
    gcry_sexp_t sexp;

    sexp = gcry_sexp_find_token(key, "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(key, "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(key, "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(key, "y", 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);

#elif defined HAVE_LIBCRYPTO
    p = make_bignum_string(key->p);
    q = make_bignum_string(key->q);
    g = make_bignum_string(key->g);
    n = make_bignum_string(key->pub_key);
    if (p == NULL || q == NULL || g == NULL || n == NULL) {
        goto error;
    }
#endif /* HAVE_LIBCRYPTO */
    if (buffer_add_ssh_string(buffer, p) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, q) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, g) < 0) {
        goto error;
    }
    if (buffer_add_ssh_string(buffer, n) < 0) {
        goto error;
    }

    rc = 0;
error:
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(sexp);
#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(n);
    ssh_string_free(n);

    return rc;
#if defined(HAVE_LIBGCRYPT) || defined(HAVE_LIBCRYPTO)
}
Esempio n. 7
0
File: keys.c Progetto: rofl0r/libssh
/**
 * @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;
}
Esempio n. 8
0
File: keys.c Progetto: rofl0r/libssh
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;
}
Esempio n. 9
0
File: pki.c Progetto: 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;
}
Esempio n. 10
0
int ssh_userauth1_password(ssh_session session, const char *username,
    const char *password) {
  ssh_string pwd = NULL;
  int rc;
  enter_function();
  rc = send_username(session, username);
  if (rc != SSH_AUTH_DENIED) {
    leave_function();
    return rc;
  }

  /* we trick a bit here. A known flaw in SSH1 protocol is that it's
   * easy to guess password sizes.
   * not that sure ...
   */

  /* XXX fix me here ! */
  /* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
  if(1 || strlen(password) >= 128) {
    /* not risky to disclose the size of such a big password .. */
    pwd = ssh_string_from_char(password);
    if (pwd == NULL) {
      leave_function();
      return SSH_AUTH_ERROR;
    }
  } else {
    /* fill the password string from random things. the strcpy
     * ensure there is at least a nul byte after the password.
     * most implementation won't see the garbage at end.
     * why garbage ? because nul bytes will be compressed by
     * gzip and disclose password len.
     */
    pwd = ssh_string_new(128);
    if (pwd == NULL) {
      leave_function();
      return SSH_AUTH_ERROR;
    }
    ssh_get_random( pwd->string, 128, 0);
    strcpy((char *) pwd->string, password);
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) {
    ssh_string_burn(pwd);
    ssh_string_free(pwd);
    leave_function();
    return SSH_AUTH_ERROR;
  }
  if (buffer_add_ssh_string(session->out_buffer, pwd) < 0) {
    ssh_string_burn(pwd);
    ssh_string_free(pwd);
    leave_function();
    return SSH_AUTH_ERROR;
  }

  ssh_string_burn(pwd);
  ssh_string_free(pwd);
  session->auth_state=SSH_AUTH_STATE_NONE;
  if (packet_send(session) == SSH_ERROR) {
    leave_function();
    return SSH_AUTH_ERROR;
  }
  rc = wait_auth1_status(session);
  leave_function();
  return rc;
}
Esempio n. 11
0
/** @internal
 * @brief launches the DH handshake state machine
 * @param session session handle
 * @returns SSH_OK or SSH_ERROR
 * @warning this function returning is no proof that DH handshake is
 * completed
 */
static int dh_handshake(ssh_session session) {
  ssh_string e = NULL;
  ssh_string f = NULL;
  ssh_string signature = NULL;
  int rc = SSH_ERROR;

  enter_function();

  switch (session->dh_handshake_state) {
    case DH_STATE_INIT:
      if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_INIT) < 0) {
        goto error;
      }

      if (dh_generate_x(session) < 0) {
        goto error;
      }
      if (dh_generate_e(session) < 0) {
        goto error;
      }

      e = dh_get_e(session);
      if (e == NULL) {
        goto error;
      }

      if (buffer_add_ssh_string(session->out_buffer, e) < 0) {
        goto error;
      }
      ssh_string_burn(e);
      ssh_string_free(e);
      e=NULL;

      rc = packet_send(session);
      if (rc == SSH_ERROR) {
        goto error;
      }

      session->dh_handshake_state = DH_STATE_INIT_SENT;
    case DH_STATE_INIT_SENT:
    	/* wait until ssh_packet_dh_reply is called */
    	break;
    case DH_STATE_NEWKEYS_SENT:
    	/* wait until ssh_packet_newkeys is called */
    	break;
    case DH_STATE_FINISHED:
    	leave_function();
      return SSH_OK;
    default:
      ssh_set_error(session, SSH_FATAL, "Invalid state in dh_handshake(): %d",
          session->dh_handshake_state);
      leave_function();
      return SSH_ERROR;
  }

  leave_function();
  return SSH_AGAIN;
error:
  if(e != NULL){
    ssh_string_burn(e);
    ssh_string_free(e);
  }
  if(f != NULL){
    ssh_string_burn(f);
    ssh_string_free(f);
  }
  if(signature != NULL){
    ssh_string_burn(signature);
    ssh_string_free(signature);
  }

  leave_function();
  return rc;
}
Esempio n. 12
0
File: pki.c Progetto: 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;
}
Esempio n. 13
0
void string_burn(ssh_string str){
  ssh_string_burn(str);
}
Esempio n. 14
0
File: kex.c Progetto: simonsj/libssh
int ssh_generate_session_keys(ssh_session session)
{
    ssh_string k_string = NULL;
    struct ssh_crypto_struct *crypto = session->next_crypto;
    unsigned char *key = NULL;
    unsigned char *IV_cli_to_srv = NULL;
    unsigned char *IV_srv_to_cli = NULL;
    unsigned char *enckey_cli_to_srv = NULL;
    unsigned char *enckey_srv_to_cli = NULL;
    unsigned char *intkey_cli_to_srv = NULL;
    unsigned char *intkey_srv_to_cli = NULL;
    size_t key_len = 0;
    size_t IV_len = 0;
    size_t enckey_cli_to_srv_len = 0;
    size_t enckey_srv_to_cli_len = 0;
    size_t intkey_cli_to_srv_len = 0;
    size_t intkey_srv_to_cli_len = 0;
    int rc = -1;

    k_string = ssh_make_bignum_string(crypto->shared_secret);
    if (k_string == NULL) {
        ssh_set_error_oom(session);
        goto error;
    }
    /* See RFC4251 Section 5 for the definition of mpint which is the
     * encoding we need to use for key in the SSH KDF */
    key = (unsigned char *)k_string;
    key_len = ssh_string_len(k_string) + 4;

    IV_len = crypto->digest_len;
    if (session->client) {
        enckey_cli_to_srv_len = crypto->out_cipher->keysize / 8;
        enckey_srv_to_cli_len = crypto->in_cipher->keysize / 8;
        intkey_cli_to_srv_len = hmac_digest_len(crypto->out_hmac);
        intkey_srv_to_cli_len = hmac_digest_len(crypto->in_hmac);
    } else {
        enckey_cli_to_srv_len = crypto->in_cipher->keysize / 8;
        enckey_srv_to_cli_len = crypto->out_cipher->keysize / 8;
        intkey_cli_to_srv_len = hmac_digest_len(crypto->in_hmac);
        intkey_srv_to_cli_len = hmac_digest_len(crypto->out_hmac);
    }

    IV_cli_to_srv = malloc(IV_len);
    IV_srv_to_cli = malloc(IV_len);
    enckey_cli_to_srv = malloc(enckey_cli_to_srv_len);
    enckey_srv_to_cli = malloc(enckey_srv_to_cli_len);
    intkey_cli_to_srv = malloc(intkey_cli_to_srv_len);
    intkey_srv_to_cli = malloc(intkey_srv_to_cli_len);
    if (IV_cli_to_srv == NULL || IV_srv_to_cli == NULL ||
        enckey_cli_to_srv == NULL || enckey_srv_to_cli == NULL ||
        intkey_cli_to_srv == NULL || intkey_srv_to_cli == NULL) {
        ssh_set_error_oom(session);
        goto error;
    }

    /* IV */
    rc = ssh_kdf(crypto, key, key_len, 'A', IV_cli_to_srv, IV_len);
    if (rc < 0) {
        goto error;
    }
    rc = ssh_kdf(crypto, key, key_len, 'B', IV_srv_to_cli, IV_len);
    if (rc < 0) {
        goto error;
    }
    /* Encryption Key */
    rc = ssh_kdf(crypto, key, key_len, 'C', enckey_cli_to_srv,
                 enckey_cli_to_srv_len);
    if (rc < 0) {
        goto error;
    }
    rc = ssh_kdf(crypto, key, key_len, 'D', enckey_srv_to_cli,
                 enckey_srv_to_cli_len);
    if (rc < 0) {
        goto error;
    }
    /* Integrity Key */
    rc = ssh_kdf(crypto, key, key_len, 'E', intkey_cli_to_srv,
                 intkey_cli_to_srv_len);
    if (rc < 0) {
        goto error;
    }
    rc = ssh_kdf(crypto, key, key_len, 'F', intkey_srv_to_cli,
                 intkey_srv_to_cli_len);
    if (rc < 0) {
        goto error;
    }

    if (session->client) {
        crypto->encryptIV = IV_cli_to_srv;
        crypto->decryptIV = IV_srv_to_cli;
        crypto->encryptkey = enckey_cli_to_srv;
        crypto->decryptkey = enckey_srv_to_cli;
        crypto->encryptMAC = intkey_cli_to_srv;
        crypto->decryptMAC = intkey_srv_to_cli;
    } else {
        crypto->encryptIV = IV_srv_to_cli;
        crypto->decryptIV = IV_cli_to_srv;
        crypto->encryptkey = enckey_srv_to_cli;
        crypto->decryptkey = enckey_cli_to_srv;
        crypto->encryptMAC = intkey_srv_to_cli;
        crypto->decryptMAC = intkey_cli_to_srv;
    }

#ifdef DEBUG_CRYPTO
    ssh_print_hexa("Client to Server IV", IV_cli_to_srv, IV_len);
    ssh_print_hexa("Server to Client IV", IV_srv_to_cli, IV_len);
    ssh_print_hexa("Client to Server Encryption Key", enckey_cli_to_srv,
                   enckey_cli_to_srv_len);
    ssh_print_hexa("Server to Client Encryption Key", enckey_srv_to_cli,
                   enckey_srv_to_cli_len);
    ssh_print_hexa("Client to Server Integrity Key", intkey_cli_to_srv,
                   intkey_cli_to_srv_len);
    ssh_print_hexa("Server to Client Integrity Key", intkey_srv_to_cli,
                   intkey_srv_to_cli_len);
#endif

    rc = 0;
error:
    ssh_string_burn(k_string);
    ssh_string_free(k_string);
    if (rc != 0) {
        free(IV_cli_to_srv);
        free(IV_srv_to_cli);
        free(enckey_cli_to_srv);
        free(enckey_srv_to_cli);
        free(intkey_cli_to_srv);
        free(intkey_srv_to_cli);
    }

    return rc;
}