예제 #1
0
파일: pki.c 프로젝트: MachalkA/libssh
/** @brief import a base64 formated key from a memory c-string
 *
 * @param   key     The key to fill, created with ssh_key_new()
 * @param   session The ssh session
 * @param   b64_key The c-string holding the base64 encoded key
 * @param   passphrase  The passphrase to decrypt the key, or NULL
 *
 * @return  SSH_ERROR in case of error, SSH_OK otherwise
 */
int ssh_pki_import_privkey_base64(ssh_key key, ssh_session session,
                    const char *b64_key, const char *passphrase) {
    ssh_private_key priv;

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

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

    priv = privatekey_from_base64(session, b64_key, 0, passphrase);
    if(priv == NULL) {
        return SSH_ERROR;
    }

    ssh_key_clean(key);

    key->dsa = priv->dsa_priv;
    key->rsa = priv->rsa_priv;
    key->type = priv->type;
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->type_c = ssh_type_to_char(key->type);

    SAFE_FREE(priv);
    return SSH_OK;
}
예제 #2
0
파일: pki.c 프로젝트: MachalkA/libssh
/**
 * @brief import a key from a file
 * @param[out]  key      the ssh_key to update
 * @param[in]  session  The SSH Session to use. If a key decryption callback is set, it will
 *                      be used to ask for the passphrase.
 * @param[in]  filename The filename of the the private key.
 * @param[in]  passphrase The passphrase to decrypt the private key. Set to null
 *                        if none is needed or it is unknown.
 * @returns SSH_OK on success, SSH_ERROR otherwise.
 **/
int ssh_key_import_private(ssh_key key, ssh_session session, const char *filename, const char *passphrase){
  ssh_private_key priv=privatekey_from_file(session,filename,0,passphrase);
  if(priv==NULL)
    return SSH_ERROR;
  ssh_key_clean(key);
  key->dsa=priv->dsa_priv;
  key->rsa=priv->rsa_priv;
  key->type=priv->type;
  key->flags=SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
  key->type_c=ssh_type_to_char(key->type);
  SAFE_FREE(priv);
  return SSH_OK;
}
예제 #3
0
int ssh_userauth_pubkey(SSH_SESSION *session, const char *username, STRING *publickey, PRIVATE_KEY *privatekey){
    STRING *user;
    STRING *service;
    STRING *method;
    STRING *algo;
    STRING *sign;
    int err=SSH_AUTH_ERROR;
    enter_function();
//    if(session->version==1)
//        return ssh_userauth1_pubkey(session,username,publickey,privatekey);
    if(!username)
        if(!(username=session->options->username)){
            if(ssh_options_default_username(session->options)){
            	leave_function();
            	return err;
            } else
                username=session->options->username;
        }
    if(ask_userauth(session)){
        leave_function();
    	return err;
    }
    user=string_from_char(username);
    service=string_from_char("ssh-connection");
    method=string_from_char("publickey");
    algo=string_from_char(ssh_type_to_char(privatekey->type));


    /* we said previously the public key was accepted */
    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    buffer_add_u8(session->out_buffer,1);
    buffer_add_ssh_string(session->out_buffer,algo);
    buffer_add_ssh_string(session->out_buffer,publickey);
    sign=ssh_do_sign(session,session->out_buffer,privatekey);
    if(sign){
        buffer_add_ssh_string(session->out_buffer,sign);
        free(sign);
        packet_send(session);
        err=wait_auth_status(session,0);
    }
    free(user);
    free(service);
    free(method);
    free(algo);
    leave_function();
    return err;
}
예제 #4
0
int ssh_userauth_offer_pubkey(SSH_SESSION *session, const char *username,int type, STRING *publickey){
    STRING *user;
    STRING *service;
    STRING *method;
    STRING *algo;
    int err=SSH_AUTH_ERROR;
    enter_function();
#ifdef HAVE_SSH1
    if(session->version==1){
        err= ssh_userauth1_offer_pubkey(session,username,type,publickey);
        leave_function();
        return err;
    }
#endif
    if(!username)
        if(!(username=session->options->username)){
            if(ssh_options_default_username(session->options)){
                leave_function();
            	return SSH_AUTH_ERROR;
            } else
                username=session->options->username;
        }
    if(ask_userauth(session)){
        leave_function();
    	return SSH_AUTH_ERROR;
    }
    user=string_from_char(username);
    service=string_from_char("ssh-connection");
    method=string_from_char("publickey");
    algo=string_from_char(ssh_type_to_char(type));

    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
    buffer_add_ssh_string(session->out_buffer,user);
    buffer_add_ssh_string(session->out_buffer,service);
    buffer_add_ssh_string(session->out_buffer,method);
    buffer_add_u8(session->out_buffer,0);
    buffer_add_ssh_string(session->out_buffer,algo);
    buffer_add_ssh_string(session->out_buffer,publickey);
    packet_send(session);
    err=wait_auth_status(session,0);
    free(user);
    free(method);
    free(service);
    free(algo);
    leave_function();
    return err;
}
예제 #5
0
파일: keys.c 프로젝트: rofl0r/libssh
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;
}
예제 #6
0
PUBLIC_KEY *publickey_from_string(SSH_SESSION *session, STRING *pubkey_s) {
  BUFFER *tmpbuf = NULL;
  STRING *type_s = NULL;
  char *type_c = NULL;
  int type;

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

  if (buffer_add_data(tmpbuf, pubkey_s->string, 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 = string_to_char(type_s);
  string_free(type_s);
  if (type_c == NULL) {
    goto error;
  }

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

  switch (type) {
    case TYPE_DSS:
      return publickey_make_dss(session, tmpbuf);
    case TYPE_RSA:
    case TYPE_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:
  buffer_free(tmpbuf);
  return NULL;
}
예제 #7
0
/** \brief makes a SSH String out of a PUBLIC_KEY object
 * \param key the public key
 * \returns a SSH String containing the public key
 * \see string_free()
 */
STRING *publickey_to_string(PUBLIC_KEY *key){
    STRING *type;
    STRING *ret;
    BUFFER *buf;
    type=string_from_char(ssh_type_to_char(key->type));
    buf=buffer_new();
    buffer_add_ssh_string(buf,type);
    switch(key->type){
        case TYPE_DSS:
            dsa_public_to_string(key->dsa_pub,buf);
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
            rsa_public_to_string(key->rsa_pub,buf);
            break;
    }
    ret=string_new(buffer_get_len(buf));
    string_fill(ret,buffer_get(buf),buffer_get_len(buf));
    buffer_free(buf);
    free(type);
    return ret;
}
예제 #8
0
파일: keys.c 프로젝트: rofl0r/libssh
/* 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;
}
예제 #9
0
파일: keys.c 프로젝트: 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;
}
예제 #10
0
파일: keys.c 프로젝트: 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;
}
예제 #11
0
STRING *signature_to_string(SIGNATURE *sign){
    STRING *str;
    STRING *rs;
#ifdef HAVE_LIBGCRYPT
    const char *r,*s;
    gcry_sexp_t sexp;
    size_t size;
#elif defined HAVE_LIBCRYPTO
    STRING *r,*s;
#endif
    unsigned char buffer[40];
    BUFFER *tmpbuf=buffer_new();
    STRING *tmp;
    tmp=string_from_char(ssh_type_to_char(sign->type));
    buffer_add_ssh_string(tmpbuf,tmp);
    free(tmp);
    switch(sign->type){
        case TYPE_DSS:
            memset(buffer,0,40);
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(sign->dsa_sign,"r",0);
            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);
            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);
            s=make_bignum_string(sign->dsa_sign->s);
            rs=string_new(40);
            memcpy(buffer,r->string+string_len(r)-20,20);
            memcpy(buffer+ 20, s->string + string_len(s) - 20, 20);
            free(r);
            free(s);
#endif
            rs=string_new(40);
            string_fill(rs,buffer,40);
            buffer_add_ssh_string(tmpbuf,rs);
            free(rs);
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(sign->rsa_sign,"s",0);
            s=gcry_sexp_nth_data(sexp,1,&size);
            if (*s == 0)
            {
              size--;
              s++;
            }
            rs=string_new(size);
            string_fill(rs,(char *)s,size);
            buffer_add_ssh_string(tmpbuf,rs);
            gcry_sexp_release(sexp);
            free(rs);
#elif defined HAVE_LIBCRYPTO
            buffer_add_ssh_string(tmpbuf,sign->rsa_sign);
#endif 
            break;
    }
    str=string_new(buffer_get_len(tmpbuf));
    string_fill(str,buffer_get(tmpbuf),buffer_get_len(tmpbuf));
    buffer_free(tmpbuf);
    return str;
}
예제 #12
0
파일: auth.c 프로젝트: CUEBoxer/OpenStudio
/**
 * @brief Try to authenticate through public key with an ssh agent.
 *
 * @param session       The ssh session to use.
 *
 * @param username      The username to authenticate. You can specify NULL if
 *                      ssh_option_set_username() has been used. You cannot try
 *                      two different logins in a row.
 *
 * @param publickey     The public key provided by the agent.
 *
 * @returns SSH_AUTH_ERROR:   A serious error happened.\n
 *          SSH_AUTH_DENIED:  Authentication failed: use another method.\n
 *          SSH_AUTH_PARTIAL: You've been partially authenticated, you still
 *                            have to use another method.\n
 *          SSH_AUTH_SUCCESS: Authentication successful.
 *
 * @see publickey_from_file()
 * @see privatekey_from_file()
 * @see privatekey_free()
 * @see ssh_userauth_offer_pubkey()
 */
int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
    ssh_public_key publickey) {
  ssh_string user = NULL;
  ssh_string service = NULL;
  ssh_string method = NULL;
  ssh_string algo = NULL;
  ssh_string key = NULL;
  ssh_string sign = NULL;
  int rc = SSH_AUTH_ERROR;

  enter_function();

  if (! agent_is_running(session)) {
    return rc;
  }

  if (username == NULL) {
    if (session->username == NULL) {
      if (ssh_options_apply(session) < 0) {
        leave_function();
        return rc;
      }
    }
    user = string_from_char(session->username);
  } else {
    user = string_from_char(username);
  }

  if (user == NULL) {
    leave_function();
    return rc;
  }

  if (ask_userauth(session) < 0) {
    string_free(user);
    leave_function();
    return rc;
  }

  service = string_from_char("ssh-connection");
  if (service == NULL) {
    goto error;
  }
  method = string_from_char("publickey");
  if (method == NULL) {
    goto error;
  }
  algo = string_from_char(ssh_type_to_char(publickey->type));
  if (algo == NULL) {
    goto error;
  }
  key = publickey_to_string(publickey);
  if (key == NULL) {
    goto error;
  }

  /* we said previously the public key was accepted */
  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST) < 0 ||
      buffer_add_ssh_string(session->out_buffer, user) < 0 ||
      buffer_add_ssh_string(session->out_buffer, service) < 0 ||
      buffer_add_ssh_string(session->out_buffer, method) < 0 ||
      buffer_add_u8(session->out_buffer, 1) < 0 ||
      buffer_add_ssh_string(session->out_buffer, algo) < 0 ||
      buffer_add_ssh_string(session->out_buffer, key) < 0) {
    goto error;
  }

  sign = ssh_do_sign_with_agent(session, session->out_buffer, publickey);

  if (sign) {
    if (buffer_add_ssh_string(session->out_buffer, sign) < 0) {
      goto error;
    }
    string_free(sign);
    if (packet_send(session) != SSH_OK) {
      leave_function();
      return rc;
    }
    rc = wait_auth_status(session,0);
  }

  string_free(user);
  string_free(service);
  string_free(method);
  string_free(algo);
  string_free(key);

  leave_function();

  return rc;
error:
  buffer_reinit(session->out_buffer);
  string_free(sign);
  string_free(user);
  string_free(service);
  string_free(method);
  string_free(algo);
  string_free(key);

  leave_function();
  return rc;
}
예제 #13
0
PUBLIC_KEY *publickey_make_dss(SSH_SESSION *session, BUFFER *buffer) {
  STRING *p = NULL;
  STRING *q = NULL;
  STRING *g = NULL;
  STRING *pubkey = NULL;
  PUBLIC_KEY *key = NULL;

  key = malloc(sizeof(PUBLIC_KEY));
  if (key == NULL) {
    buffer_free(buffer);
    return NULL;
  }

  key->type = TYPE_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);

  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)))",
      string_len(p), p->string,
      string_len(q), q->string,
      string_len(g), g->string,
      string_len(pubkey), pubkey->string);
  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", p->string, string_len(p));
  ssh_print_hexa("q", q->string, string_len(q));
  ssh_print_hexa("g", g->string, string_len(g));
#endif

  string_burn(p);
  string_free(p);
  string_burn(q);
  string_free(q);
  string_burn(g);
  string_free(g);
  string_burn(pubkey);
  string_free(pubkey);

  return key;
error:
  string_burn(p);
  string_free(p);
  string_burn(q);
  string_free(q);
  string_burn(g);
  string_free(g);
  string_burn(pubkey);
  string_free(pubkey);
  publickey_free(key);

  return NULL;
}
예제 #14
0
PUBLIC_KEY *publickey_make_rsa(SSH_SESSION *session, BUFFER *buffer,
    int type) {
  STRING *e = NULL;
  STRING *n = NULL;
  PUBLIC_KEY *key = NULL;

  key = malloc(sizeof(PUBLIC_KEY));
  if (key == NULL) {
    buffer_free(buffer);
    return NULL;
  }

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

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

  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)))",
      string_len(n), n->string,
      string_len(e),e->string);
  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", e->string, string_len(e));
  ssh_print_hexa("n", n->string, string_len(n));
#endif

  string_burn(e);
  string_free(e);
  string_burn(n);
  string_free(n);

  return key;
error:
  string_burn(e);
  string_free(e);
  string_burn(n);
  string_free(n);
  publickey_free(key);

  return NULL;
}
예제 #15
0
파일: keys.c 프로젝트: 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;
}
예제 #16
0
/** \brief Makes a PUBLIC_KEY object out of a PRIVATE_KEY object
 * \param prv the Private key
 * \returns the public key
 * \see publickey_to_string()
 */
PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv){
    PUBLIC_KEY *key=malloc(sizeof(PUBLIC_KEY));
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sexp;
    const char *tmp;
    size_t size;
    STRING *p,*q,*g,*y,*e,*n;
#endif
    key->type=prv->type;
    switch(key->type){
        case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(prv->dsa_priv,"p",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            p=string_new(size);
            string_fill(p,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->dsa_priv,"q",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            q=string_new(size);
            string_fill(q,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->dsa_priv,"g",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            g=string_new(size);
            string_fill(g,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->dsa_priv,"y",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            y=string_new(size);
            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)))",string_len(p),p->string,string_len(q),q->string,string_len(g),g->string,string_len(y),y->string);
            free(p);
            free(q);
            free(g);
            free(y);
#elif defined HAVE_LIBCRYPTO
            key->dsa_pub=DSA_new();
            key->dsa_pub->p=BN_dup(prv->dsa_priv->p);
            key->dsa_pub->q=BN_dup(prv->dsa_priv->q);
            key->dsa_pub->pub_key=BN_dup(prv->dsa_priv->pub_key);
            key->dsa_pub->g=BN_dup(prv->dsa_priv->g);
#endif
            break;
        case TYPE_RSA:
        case TYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
            sexp=gcry_sexp_find_token(prv->rsa_priv,"n",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            n=string_new(size);
            string_fill(n,(char *)tmp,size);
            gcry_sexp_release(sexp);
            sexp=gcry_sexp_find_token(prv->rsa_priv,"e",0);
            tmp=gcry_sexp_nth_data(sexp,1,&size);
            e=string_new(size);
            string_fill(e,(char *)tmp,size);
            gcry_sexp_release(sexp);
            gcry_sexp_build(&key->rsa_pub,NULL,"(public-key(rsa(n %b)(e %b)))",string_len(n),n->string,string_len(e),e->string);
            free(e);
            free(n);
#elif defined HAVE_LIBCRYPTO
            key->rsa_pub=RSA_new();
            key->rsa_pub->e=BN_dup(prv->rsa_priv->e);
            key->rsa_pub->n=BN_dup(prv->rsa_priv->n);
#endif
            break;
    }
    key->type_c=ssh_type_to_char(prv->type);
    return key;
}
예제 #17
0
파일: keys.c 프로젝트: rofl0r/libssh
/* 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;
}
예제 #18
0
파일: auth.c 프로젝트: CUEBoxer/OpenStudio
/**
 * @brief Try to authenticate through public key.
 *
 * @param session       The ssh session to use.
 *
 * @param username      The username to authenticate. You can specify NULL if
 *                      ssh_option_set_username() has been used. You cannot try
 *                      two different logins in a row.
 *
 * @param type          The type of the public key. This value is given by
 *                      publickey_from_file().
 *
 * @param publickey     A public key returned by publickey_from_file().
 *
 * @returns SSH_AUTH_ERROR:   A serious error happened.\n
 *          SSH_AUTH_DENIED:  The server doesn't accept that public key as an
 *                            authentication token. Try another key or another
 *                            method.\n
 *          SSH_AUTH_PARTIAL: You've been partially authenticated, you still
 *                            have to use another method.\n
 *          SSH_AUTH_SUCCESS: The public key is accepted, you want now to use
 *                            ssh_userauth_pubkey().
 *
 * @see publickey_from_file()
 * @see privatekey_from_file()
 * @see ssh_userauth_pubkey()
 */
int ssh_userauth_offer_pubkey(ssh_session session, const char *username,
    int type, ssh_string publickey) {
  ssh_string user = NULL;
  ssh_string service = NULL;
  ssh_string method = NULL;
  ssh_string algo = NULL;
  int rc = SSH_AUTH_ERROR;

  enter_function();

#ifdef WITH_SSH1
  if (session->version == 1) {
    ssh_userauth1_offer_pubkey(session, username, type, publickey);
    leave_function();
    return rc;
  }
#endif

  if (username == NULL) {
    if (session->username == NULL) {
      if (ssh_options_apply(session) < 0) {
        leave_function();
        return rc;
      }
    }
    user = string_from_char(session->username);
  } else {
    user = string_from_char(username);
  }

  if (user == NULL) {
    leave_function();
    return rc;
  }

  if (ask_userauth(session) < 0) {
    string_free(user);
    leave_function();
    return rc;
  }

  service = string_from_char("ssh-connection");
  if (service == NULL) {
    goto error;
  }
  method = string_from_char("publickey");
  if (method == NULL) {
    goto error;
  }
  algo = string_from_char(ssh_type_to_char(type));
  if (algo == NULL) {
    goto error;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST) < 0 ||
      buffer_add_ssh_string(session->out_buffer, user) < 0 ||
      buffer_add_ssh_string(session->out_buffer, service) < 0 ||
      buffer_add_ssh_string(session->out_buffer, method) < 0 ||
      buffer_add_u8(session->out_buffer, 0) < 0 ||
      buffer_add_ssh_string(session->out_buffer, algo) < 0 ||
      buffer_add_ssh_string(session->out_buffer, publickey) < 0) {
    goto error;
  }

  string_free(user);
  string_free(method);
  string_free(service);
  string_free(algo);

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }
  rc = wait_auth_status(session,0);

  leave_function();
  return rc;
error:
  buffer_reinit(session->out_buffer);
  string_free(user);
  string_free(method);
  string_free(service);
  string_free(algo);

  leave_function();
  return rc;
}