예제 #1
0
static void rsa_public_to_string(gcry_sexp_t key, BUFFER *buffer){
#elif defined HAVE_LIBCRYPTO
static void rsa_public_to_string(RSA *key, BUFFER *buffer){
#endif
    STRING *e, *n;
#ifdef HAVE_LIBGCRYPT
    const char *tmp;
    size_t size;
    gcry_sexp_t sexp;
    sexp=gcry_sexp_find_token(key,"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(key,"e",0);
    tmp=gcry_sexp_nth_data(sexp,1,&size);
    e=string_new(size);
    string_fill(e,(char *)tmp,size);
    gcry_sexp_release(sexp);
#elif defined HAVE_LIBCRYPTO
    e=make_bignum_string(key->e);
    n=make_bignum_string(key->n);
#endif
    buffer_add_ssh_string(buffer,e);
    buffer_add_ssh_string(buffer,n);
    free(e);
    free(n);
}
예제 #2
0
/* this is a public key in openssh's format */
static STRING *make_rsa1_string(STRING *e, STRING *n){
  BUFFER *buffer = NULL;
  STRING *rsa = NULL;
  STRING *ret = NULL;

  buffer = buffer_new();
  rsa = string_from_char("ssh-rsa1");

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

  ret = string_new(buffer_get_len(buffer));
  if (ret == NULL) {
    goto error;
  }

  string_fill(ret, buffer_get(buffer), buffer_get_len(buffer));
error:
  buffer_free(buffer);
  string_free(rsa);

  return ret;
}
예제 #3
0
static STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *srvkey,
    PUBLIC_KEY *hostkey, int slen, int hlen) {
  unsigned char buffer[32] = {0};
  int i;
  STRING *data1 = NULL;
  STRING *data2 = NULL;

  /* first, generate a session key */
  ssh_get_random(session->next_crypto->encryptkey, 32, 1);
  memcpy(buffer, session->next_crypto->encryptkey, 32);
  memcpy(session->next_crypto->decryptkey, session->next_crypto->encryptkey, 32);

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("session key",buffer,32);
#endif

  /* xor session key with session_id */
  for (i = 0; i < 16; i++) {
    buffer[i] ^= session->next_crypto->session_id[i];
  }
  data1 = string_new(32);
  if (data1 == NULL) {
    return NULL;
  }
  string_fill(data1, buffer, 32);
  if (ABS(hlen - slen) < 128){
    ssh_log(session, SSH_LOG_FUNCTIONS,
        "Difference between server modulus and host modulus is only %d. "
        "It's illegal and may not work",
        ABS(hlen - slen));
  }

  if (modulus_smaller(srvkey, hostkey)) {
    data2 = ssh_encrypt_rsa1(session, data1, srvkey);
    string_free(data1);
    data1 = NULL;
    if (data2 == NULL) {
      return NULL;
    }
    data1 = ssh_encrypt_rsa1(session, data2, hostkey);
    string_free(data2);
    if (data1 == NULL) {
      return NULL;
    }
  } else {
    data2 = ssh_encrypt_rsa1(session, data1, hostkey);
    string_free(data1);
    data1 = NULL;
    if (data2 == NULL) {
      return NULL;
    }
    data1 = ssh_encrypt_rsa1(session, data2, srvkey);
    string_free(data2);
    if (data1 == NULL) {
      return NULL;
    }
  }

  return data1;
}
예제 #4
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/*
 * This function concats in a buffer the values needed to do a signature
 * verification. */
ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, char *service) {
/*
     The value of 'signature' is a signature by the corresponding private
   key over the following data, in the following order:

      string    session identifier
      byte      SSH_MSG_USERAUTH_REQUEST
      string    user name
      string    service name
      string    "publickey"
      boolean   TRUE
      string    public key algorithm name
      string    public key to be used for authentication
*/
	struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto :
                                             session->next_crypto;
  ssh_buffer buffer = NULL;
  ssh_string session_id = NULL;
  uint8_t type = SSH2_MSG_USERAUTH_REQUEST;
  ssh_string username = string_from_char(msg->auth_request.username);
  ssh_string servicename = string_from_char(service);
  ssh_string method = string_from_char("publickey");
  uint8_t has_sign = 1;
  ssh_string algo = string_from_char(msg->auth_request.public_key->type_c);
  ssh_string publickey = publickey_to_string(msg->auth_request.public_key);

  buffer = buffer_new();
  if (buffer == NULL) {
    goto error;
  }
  session_id = string_new(SHA_DIGEST_LEN);
  if (session_id == NULL) {
    buffer_free(buffer);
    buffer = NULL;
    goto error;
  }
  string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);

  if(buffer_add_ssh_string(buffer, session_id) < 0 ||
     buffer_add_u8(buffer, type) < 0 ||
     buffer_add_ssh_string(buffer, username) < 0 ||
     buffer_add_ssh_string(buffer, servicename) < 0 ||
     buffer_add_ssh_string(buffer, method) < 0 ||
     buffer_add_u8(buffer, has_sign) < 0 ||
     buffer_add_ssh_string(buffer, algo) < 0 ||
     buffer_add_ssh_string(buffer, publickey) < 0) {
    buffer_free(buffer);
    buffer = NULL;
    goto error;
  }

error:
  if(session_id) string_free(session_id);
  if(username) string_free(username);
  if(servicename) string_free(servicename);
  if(method) string_free(method);
  if(algo) string_free(algo);
  if(publickey) string_free(publickey);
  return buffer;
}
예제 #5
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/*
 * Maybe the missing function from libcrypto
 *
 * I think now, maybe it's a bad idea to name it has it should have be
 * named in libcrypto
 */
static ssh_string RSA_do_sign(const unsigned char *payload, int len, RSA *privkey) {
  ssh_string sign = NULL;
  unsigned char *buffer = NULL;
  unsigned int size;

  buffer = malloc(RSA_size(privkey));
  if (buffer == NULL) {
    return NULL;
  }

  if (RSA_sign(NID_sha1, payload, len, buffer, &size, privkey) == 0) {
    SAFE_FREE(buffer);
    return NULL;
  }

  sign = string_new(size);
  if (sign == NULL) {
    SAFE_FREE(buffer);
    return NULL;
  }

  string_fill(sign, buffer, size);
  SAFE_FREE(buffer);

  return sign;
}
예제 #6
0
STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *svrkey,
        PUBLIC_KEY *hostkey,int slen, int hlen ){
    unsigned char buffer[32];
    int i;
    STRING *data1,*data2;
    /* first, generate a session key */
    
    ssh_get_random(session->next_crypto->encryptkey,32,1);
    memcpy(buffer,session->next_crypto->encryptkey,32);
    memcpy(session->next_crypto->decryptkey,
            session->next_crypto->encryptkey,32);
#ifdef DEBUG_CRYPTO
    ssh_print_hexa("session key",buffer,32);
#endif
    /* xor session key with session_id */
    for (i=0;i<16;++i)
        buffer[i]^=session->next_crypto->session_id[i];
    data1=string_new(32);
    string_fill(data1,buffer,32);
    if(ABS(hlen-slen)<128){
        ssh_say(1,"Difference between server modulus and host modulus is only %d. It's illegal and may not work\n",
                ABS(hlen-slen));
    }
    if(modulus_smaller(svrkey,hostkey)){
        data2=ssh_encrypt_rsa1(session,data1,svrkey);
        free(data1);
        data1=ssh_encrypt_rsa1(session,data2,hostkey);
    } else {
        data2=ssh_encrypt_rsa1(session,data1,hostkey);
        free(data1);
        data1=ssh_encrypt_rsa1(session,data2,svrkey);
    }
    return data1;
}
예제 #7
0
STRING *ssh_encrypt_rsa1(SSH_SESSION *session, STRING *data, PUBLIC_KEY *key){
    int len=string_len(data);
#ifdef HAVE_LIBGCRYPT
    STRING *ret;
    gcry_sexp_t ret_sexp;
    gcry_sexp_t data_sexp;
    const char *tmp;
    size_t size;
    gcry_sexp_build(&data_sexp,NULL,"(data(flags pkcs1)(value %b))",len,data->string);
    gcry_pk_encrypt(&ret_sexp,data_sexp,key->rsa_pub);
    gcry_sexp_release(data_sexp);
    data_sexp=gcry_sexp_find_token(ret_sexp,"a",0);
    tmp=gcry_sexp_nth_data(data_sexp,1,&size);
    if (*tmp == 0)
    {
      size--;
      tmp++;
    }
    ret=string_new(size);
    string_fill(ret,(char *)tmp,size);
    gcry_sexp_release(ret_sexp);
#elif defined HAVE_LIBCRYPTO
    int flen=RSA_size(key->rsa_pub);
    STRING *ret=string_new(flen);
    RSA_public_encrypt(len,data->string,ret->string,key->rsa_pub,
            RSA_PKCS1_PADDING);
#endif
    return ret;
}
예제 #8
0
static void dsa_public_to_string(gcry_sexp_t key, BUFFER *buffer){
#elif defined HAVE_LIBCRYPTO
static void dsa_public_to_string(DSA *key, BUFFER *buffer){
#endif
    STRING *p,*q,*g,*n;
#ifdef HAVE_LIBGCRYPT
    const char *tmp;
    size_t size;
    gcry_sexp_t sexp;
    sexp=gcry_sexp_find_token(key,"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(key,"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(key,"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(key,"y",0);
    tmp=gcry_sexp_nth_data(sexp,1,&size);
    n=string_new(size);
    string_fill(n,(char *)tmp,size);
    gcry_sexp_release(sexp);
#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);
#endif
    buffer_add_ssh_string(buffer,p);
    buffer_add_ssh_string(buffer,q);
    buffer_add_ssh_string(buffer,g);
    buffer_add_ssh_string(buffer,n);
    free(p);
    free(q);
    free(g);
    free(n);
}
예제 #9
0
파일: client.c 프로젝트: AndrienkoF/KPIRepo
void string_fromJSON(string_t* newString, char * string){
    cJSON* jList = cJSON_CreateObject();
    jList = cJSON_Parse(string);
    char* author = cJSON_GetObjectItem(jList, "author")->valuestring;
    char* quote = cJSON_GetObjectItem(jList, "quote")->valuestring;

    time_t arrayTime;
    struct tm* ourTime;

    time(&arrayTime);
    ourTime = localtime(&arrayTime);
    string_fill(newString, author, quote, asctime(ourTime));
}
예제 #10
0
/* this is a public key in openssh's format */
static STRING *make_rsa1_string(STRING *e, STRING *n){
    BUFFER *buffer=buffer_new();
    STRING *rsa=string_from_char("ssh-rsa1");
    STRING *ret;
    buffer_add_ssh_string(buffer,rsa);
    free(rsa);
    buffer_add_ssh_string(buffer,e);
    buffer_add_ssh_string(buffer,n);
    ret=string_new(buffer_get_len(buffer));
    string_fill(ret,buffer_get(buffer),buffer_get_len(buffer));
    buffer_free(buffer);
    return ret;
}
예제 #11
0
/* i think now, maybe it's a bad idea to name it has it should have be named in libcrypto */
static STRING *RSA_do_sign(void *payload,int len,RSA *privkey){
    STRING *sign;
    void *buffer=malloc(RSA_size(privkey));
    unsigned int size;
    int err;
    err=RSA_sign(NID_sha1,payload,len,buffer,&size,privkey);
    if(!err){
        free(buffer);
        return NULL;
    }
    sign=string_new(size);
    string_fill(sign,buffer,size);
    free(buffer);
    return sign;
}
예제 #12
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
ssh_string ssh_do_sign_with_agent(ssh_session session,
    struct ssh_buffer_struct *buf, struct ssh_public_key_struct *publickey) {
  struct ssh_buffer_struct *sigbuf = NULL;
  struct ssh_string_struct *signature = NULL;
  struct ssh_string_struct *session_id = NULL;
  struct ssh_crypto_struct *crypto = NULL;

  if (session->current_crypto) {
    crypto = session->current_crypto;
  } else {
    crypto = session->next_crypto;
  }

  /* prepend session identifier */
  session_id = string_new(SHA_DIGEST_LEN);
  if (session_id == NULL) {
    return NULL;
  }
  string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);

  sigbuf = buffer_new();
  if (sigbuf == NULL) {
    string_free(session_id);
    return NULL;
  }

  if (buffer_add_ssh_string(sigbuf, session_id) < 0) {
    buffer_free(sigbuf);
    string_free(session_id);
    return NULL;
  }
  string_free(session_id);

  /* append out buffer */
  if (buffer_add_buffer(sigbuf, buf) < 0) {
    buffer_free(sigbuf);
    return NULL;
  }

  /* create signature */
  signature = agent_sign_data(session, sigbuf, publickey);

  buffer_free(sigbuf);

  return signature;
}
예제 #13
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/** \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()
 */
ssh_string publickey_to_string(ssh_public_key key) {
  ssh_string type = NULL;
  ssh_string ret = NULL;
  ssh_buffer buf = NULL;

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

  type = string_from_char(key->type_c);
  if (type == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buf, type) < 0) {
    goto error;
  }

  switch (key->type) {
    case TYPE_DSS:
      if (dsa_public_to_string(key->dsa_pub, buf) < 0) {
        goto error;
      }
      break;
    case TYPE_RSA:
    case TYPE_RSA1:
      if (rsa_public_to_string(key->rsa_pub, buf) < 0) {
        goto error;
      }
      break;
  }

  ret = string_new(buffer_get_len(buf));
  if (ret == NULL) {
    goto error;
  }

  string_fill(ret, buffer_get(buf), buffer_get_len(buf));
error:
  buffer_free(buf);
  string_free(type);

  return ret;
}
예제 #14
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;
}
예제 #15
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/* Signature decoding functions */
static 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 = buffer_new();
  if (tmpbuf == NULL) {
    return NULL;
  }

  tmp = string_from_char(ssh_type_to_char(sign->type));
  if (tmp == NULL) {
    buffer_free(tmpbuf);
    return NULL;
  }
  if (buffer_add_ssh_string(tmpbuf, tmp) < 0) {
    buffer_free(tmpbuf);
    string_free(tmp);
    return NULL;
  }
  string_free(tmp);

  switch(sign->type) {
    case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
      sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0);
      if (sexp == NULL) {
        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) {
        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) {
        buffer_free(tmpbuf);
        return NULL;
      }
      s = make_bignum_string(sign->dsa_sign->s);
      if (s == NULL) {
        buffer_free(tmpbuf);
        string_free(r);
        return NULL;
      }

      memcpy(buffer, (char *)string_data(r) + string_len(r) - 20, 20);
      memcpy(buffer + 20, (char *)string_data(s) + string_len(s) - 20, 20);

      string_free(r);
      string_free(s);
#endif /* HAVE_LIBCRYPTO */
      rs = string_new(40);
      if (rs == NULL) {
        buffer_free(tmpbuf);
        return NULL;
      }

      string_fill(rs, buffer, 40);
      rc = buffer_add_ssh_string(tmpbuf, rs);
      string_free(rs);
      if (rc < 0) {
        buffer_free(tmpbuf);
        return NULL;
      }

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

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

  str = string_new(buffer_get_len(tmpbuf));
  if (str == NULL) {
    buffer_free(tmpbuf);
    return NULL;
  }
  string_fill(str, buffer_get(tmpbuf), buffer_get_len(tmpbuf));
  buffer_free(tmpbuf);

  return str;
}
예제 #16
0
/* this function signs the session id (known as H) as a string then the content of sigbuf */
STRING *ssh_do_sign(SSH_SESSION *session,BUFFER *sigbuf, PRIVATE_KEY *privatekey){
    SHACTX ctx;
    STRING *session_str=string_new(SHA_DIGEST_LEN);
    unsigned char hash[SHA_DIGEST_LEN+1];
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t gcryhash;
#endif
    SIGNATURE *sign;
    STRING *signature;
    CRYPTO *crypto=session->current_crypto?session->current_crypto:session->next_crypto;
    string_fill(session_str,crypto->session_id,SHA_DIGEST_LEN);
    ctx=sha1_init();
    sha1_update(ctx,session_str,string_len(session_str)+4);
    sha1_update(ctx,buffer_get(sigbuf),buffer_get_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
    free(session_str);
    sign=malloc(sizeof(SIGNATURE));
    switch(privatekey->type){
        case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
            gcry_sexp_build(&gcryhash,NULL,"%b",SHA_DIGEST_LEN+1,hash);
            gcry_pk_sign(&sign->dsa_sign,gcryhash,privatekey->dsa_priv);
#elif defined HAVE_LIBCRYPTO
            sign->dsa_sign=DSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->dsa_priv);
#ifdef DEBUG_CRYPTO
            ssh_print_bignum("r",sign->dsa_sign->r);
            ssh_print_bignum("s",sign->dsa_sign->s);
#endif
#endif
            sign->rsa_sign=NULL;
            break;
        case TYPE_RSA:
#ifdef HAVE_LIBGCRYPT
            gcry_sexp_build(&gcryhash,NULL,"(data(flags pkcs1)(hash sha1 %b))",SHA_DIGEST_LEN,hash+1);
            gcry_pk_sign(&sign->rsa_sign,gcryhash,privatekey->rsa_priv);
#elif defined HAVE_LIBCRYPTO
            sign->rsa_sign=RSA_do_sign(hash+1,SHA_DIGEST_LEN,privatekey->rsa_priv);
#endif
            sign->dsa_sign=NULL;
            break;
    }
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_release(gcryhash);
#endif
    sign->type=privatekey->type;
    if(!sign->dsa_sign && !sign->rsa_sign){
#ifdef HAVE_LIBGCRYPT
        ssh_set_error(session,SSH_FATAL,"Signing : libcrypt error");
#elif HAVE_LIBCRYPTO
        ssh_set_error(session,SSH_FATAL,"Signing : openssl error");
#endif
        signature_free(sign);
        return NULL;
    }
    signature=signature_to_string(sign);
    signature_free(sign);
    return signature;
}
예제 #17
0
/* TODO : split this function in two so it becomes smaller */
SIGNATURE *signature_from_string(SSH_SESSION *session, STRING *signature,PUBLIC_KEY *pubkey,int needed_type){
#ifdef HAVE_LIBGCRYPT
    gcry_sexp_t sig;
#elif defined HAVE_LIBCRYPTO
    DSA_SIG *sig;
    STRING *r,*s;
#endif
    SIGNATURE *sign=malloc(sizeof(SIGNATURE));
    BUFFER *tmpbuf=buffer_new();
    STRING *rs;
    STRING *type_s,*e;
    int len,rsalen;
    char *type;
    buffer_add_data(tmpbuf,signature->string,string_len(signature));
    type_s=buffer_get_ssh_string(tmpbuf);
    if(!type_s){
        ssh_set_error(session,SSH_FATAL,"Invalid signature packet");
        buffer_free(tmpbuf);
        return NULL;
    }
    type=string_to_char(type_s);
    free(type_s);
    switch(needed_type){
        case TYPE_DSS:
            if(strcmp(type,"ssh-dss")){
                ssh_set_error(session,SSH_FATAL,"Invalid signature type : %s",type);
                buffer_free(tmpbuf);
                free(type);
                return NULL;
            }
            break;
        case TYPE_RSA:
            if(strcmp(type,"ssh-rsa")){
                ssh_set_error(session,SSH_FATAL,"Invalid signature type : %s",type);
                buffer_free(tmpbuf);
                free(type);
                return NULL;
            }
            break;
        default:
            ssh_set_error(session,SSH_FATAL,"Invalid signature type : %s",type);
            free(type);
            buffer_free(tmpbuf);
            return NULL;
    }
    free(type);
    switch(needed_type){
        case TYPE_DSS:
            rs=buffer_get_ssh_string(tmpbuf);
            buffer_free(tmpbuf);
            if(!rs || string_len(rs)!=40){ /* 40 is the dual signature blob len. */
                if(rs)
                    free(rs);
                return NULL;
            }
            /* we make use of strings (because we have all-made functions to convert them to bignums (ou pas ;)*/
#ifdef HAVE_LIBGCRYPT
            gcry_sexp_build(&sig,NULL,"(sig-val(dsa(r %b)(s %b)))",20,rs->string,20,rs->string+20);
#elif defined HAVE_LIBCRYPTO
            r=string_new(20);
            s=string_new(20);
            string_fill(r,rs->string,20);
            string_fill(s,rs->string+20,20);
            sig=DSA_SIG_new();
            sig->r=make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
            sig->s=make_string_bn(s);
            free(r);
            free(s);
#endif
#ifdef DEBUG_CRYPTO
            ssh_print_hexa("r",rs->string,20);
            ssh_print_hexa("s",rs->string+20,20);
#endif
            free(rs);
            sign->type=TYPE_DSS;
            sign->dsa_sign=sig;
            return sign;
        case TYPE_RSA:
            e=buffer_get_ssh_string(tmpbuf);
            buffer_free(tmpbuf);
            if(!e){
                return NULL;
            }
            len=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){
                free(e);
                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=TYPE_RSA;
#ifdef HAVE_LIBGCRYPT
            gcry_sexp_build(&sig,NULL,"(sig-val(rsa(s %b)))",string_len(e),e->string);
            sign->rsa_sign=sig;
#elif defined HAVE_LIBCRYPTO
            sign->rsa_sign=e;
#endif
#ifdef DEBUG_CRYPTO
            ssh_say(0,"Len : %d\n",len);
            ssh_print_hexa("rsa signature",e->string,len);
#endif
#ifdef HAVE_LIBGCRYPT
            free(e);
#endif
            return sign;
        default:
            return NULL;
    }
}
예제 #18
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;
}
예제 #19
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/*
 * This function signs the session id (known as H) as a string then
 * the content of sigbuf */
ssh_string ssh_do_sign(ssh_session session, ssh_buffer sigbuf,
    ssh_private_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;
  SIGNATURE *sign = NULL;
  SHACTX ctx = NULL;
#ifdef HAVE_LIBGCRYPT
  gcry_sexp_t gcryhash;
#endif

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

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

  sha1_update(ctx, session_str, string_len(session_str) + 4);
  string_free(session_str);
  sha1_update(ctx, buffer_get(sigbuf), buffer_get_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 = malloc(sizeof(SIGNATURE));
  if (sign == NULL) {
    return NULL;
  }

  switch(privatekey->type) {
    case TYPE_DSS:
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN + 1, hash) ||
          gcry_pk_sign(&sign->dsa_sign, gcryhash, privatekey->dsa_priv)) {
        ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error");
        gcry_sexp_release(gcryhash);
        signature_free(sign);
        return NULL;
      }
#elif defined HAVE_LIBCRYPTO
      sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN,
          privatekey->dsa_priv);
      if (sign->dsa_sign == NULL) {
        ssh_set_error(session, SSH_FATAL, "Signing: openssl error");
        signature_free(sign);
        return NULL;
      }
#ifdef DEBUG_CRYPTO
      ssh_print_bignum("r", sign->dsa_sign->r);
      ssh_print_bignum("s", sign->dsa_sign->s);
#endif
#endif /* HAVE_LIBCRYPTO */
      sign->rsa_sign = NULL;
      break;
    case TYPE_RSA:
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&gcryhash, NULL, "(data(flags pkcs1)(hash sha1 %b))",
            SHA_DIGEST_LEN, hash + 1) ||
          gcry_pk_sign(&sign->rsa_sign, gcryhash, privatekey->rsa_priv)) {
        ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error");
        gcry_sexp_release(gcryhash);
        signature_free(sign);
        return NULL;
      }
#elif defined HAVE_LIBCRYPTO
      sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN,
          privatekey->rsa_priv);
      if (sign->rsa_sign == NULL) {
        ssh_set_error(session, SSH_FATAL, "Signing: openssl error");
        signature_free(sign);
        return NULL;
      }
#endif
      sign->dsa_sign = NULL;
      break;
  }
#ifdef HAVE_LIBGCRYPT
  gcry_sexp_release(gcryhash);
#endif

  sign->type = privatekey->type;

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

  return signature;
}
예제 #20
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;
}
예제 #21
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
ssh_string ssh_encrypt_rsa1(ssh_session session, ssh_string data, ssh_public_key key) {
  ssh_string str = NULL;
  size_t len = 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, 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 = 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;
  }
  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 = string_new(size);
  if (str == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return NULL;
  }

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

  return str;
}
예제 #22
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/** \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()
 */
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;
  }

  key->type = prv->type;
  switch(key->type) {
    case TYPE_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 = string_new(size);
      if (p == NULL) {
        goto error;
      }
      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 = string_new(size);
      if (q == NULL) {
        goto error;
      }
      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 = string_new(size);
      if (g == NULL) {
        goto error;
      }
      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 = string_new(size);
      if (y == NULL) {
        goto error;
      }
      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), string_data(p),
          string_len(q), string_data(q),
          string_len(g), string_data(g),
          string_len(y), string_data(y));

      string_burn(p);
      string_free(p);
      string_burn(q);
      string_free(q);
      string_burn(g);
      string_free(g);
      string_burn(y);
      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 TYPE_RSA:
    case TYPE_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 = string_new(size);
      if (n == NULL) {
        goto error;
      }
      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 = string_new(size);
      if (e == NULL) {
        goto error;
      }
      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), string_data(n),
          string_len(e), string_data(e));
      if (key->rsa_pub == NULL) {
        goto error;
      }

      string_burn(e);
      string_free(e);
      string_burn(n);
      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;
  }
  key->type_c = ssh_type_to_char(prv->type);

  return key;
error:
#ifdef HAVE_LIBGCRYPT
  gcry_sexp_release(sexp);
  string_burn(p);
  string_free(p);
  string_burn(q);
  string_free(q);
  string_burn(g);
  string_free(g);
  string_burn(y);
  string_free(y);

  string_burn(e);
  string_free(e);
  string_burn(n);
  string_free(n);
#endif
  publickey_free(key);

  return NULL;
}
예제 #23
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
/* 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;
  }

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

  if (buffer_add_data(tmpbuf, string_data(signature), string_len(signature)) < 0) {
    signature_free(sign);
    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);
    buffer_free(tmpbuf);
    return NULL;
  }

  type_c = string_to_char(type_s);
  string_free(type_s);
  if (type_c == NULL) {
    signature_free(sign);
    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);
    buffer_free(tmpbuf);
    return NULL;
  }

  switch(needed_type) {
    case TYPE_DSS:
      rs = buffer_get_ssh_string(tmpbuf);
      buffer_free(tmpbuf);

      /* 40 is the dual signature blob len. */
      if (rs == NULL || string_len(rs) != 40) {
        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 ,string_data(rs), 20,(unsigned char *)string_data(rs) + 20)) {
        string_free(rs);
        signature_free(sign);
        return NULL;
      }
#elif defined HAVE_LIBCRYPTO
      r = string_new(20);
      s = string_new(20);
      if (r == NULL || s == NULL) {
        string_free(r);
        string_free(s);
        string_free(rs);
        signature_free(sign);
        return NULL;
      }

      string_fill(r, string_data(rs), 20);
      string_fill(s, (char *)string_data(rs) + 20, 20);

      sig = DSA_SIG_new();
      if (sig == NULL) {
        string_free(r);
        string_free(s);
        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);
      string_free(r);
      string_free(s);

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

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

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

      return sign;
    case TYPE_RSA:
      e = buffer_get_ssh_string(tmpbuf);
      buffer_free(tmpbuf);
      if (e == NULL) {
        signature_free(sign);
        return NULL;
      }
      len = 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) {
        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 = TYPE_RSA;
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
          string_len(e), string_data(e))) {
        signature_free(sign);
        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", string_data(e), len);
#endif

#ifdef HAVE_LIBGCRYPT
      string_free(e);
#endif

      return sign;
    default:
      return NULL;
  }

  return NULL;
}
예제 #24
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
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 = string_new(size);
  if (p == NULL) {
    goto error;
  }
  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 = string_new(size);
  if (q == NULL) {
    goto error;
  }
  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 = string_new(size);
  if (g == NULL) {
    goto error;
  }
  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 = string_new(size);
  if (n == NULL) {
    goto error;
  }
  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

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

  return rc;
}
예제 #25
0
파일: keys.c 프로젝트: CUEBoxer/OpenStudio
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 = string_new(size);
  if (n == NULL) {
    goto error;
  }
  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 = string_new(size);
  if (e == NULL) {
    goto error;
  }
  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

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

  return rc;
}