Esempio n. 1
0
BCW_API hd_private_key::hd_private_key(const data_chunk& seed, bool testnet)
  : hd_public_key()
{
    std::string key("Bitcoin seed");
    split_long_hash I = split(hmac_sha512_hash(seed, to_data_chunk(key)));

    // The key is invalid if parse256(IL) >= n or 0:
    if (!verify_private_key(I.L))
        return;

    auto lineage = hd_key_lineage{testnet, 0, 0, 0};
    *this = hd_private_key(I.L, I.R, lineage);
}
Esempio n. 2
0
data_chunk sign(ec_secret secret, hash_digest hash, ec_secret nonce)
{
    std::reverse(hash.begin(), hash.end());
    init.init();
    int out_size = 72;
    data_chunk signature(out_size);

    if (!verify_private_key(nonce)) // Needed because of upstream bug
        return data_chunk();
    bool valid = secp256k1_ecdsa_sign(hash.data(), hash.size(),
        signature.data(), &out_size, secret.data(), nonce.data()) == 1;
    if (!valid)
        return data_chunk();

    signature.resize(out_size);
    return signature;
}
Esempio n. 3
0
BC_API ec_secret create_nonce(ec_secret secret, hash_digest hash)
{
    std::reverse(hash.begin(), hash.end());
    init.init();

    hash_digest K
    {{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    }};
    hash_digest V
    {{
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
    }};

    K = hmac_sha256_hash(V + byte_array<1>{{0x00}} + secret + hash, K);
    V = hmac_sha256_hash(V, K);
    K = hmac_sha256_hash(V + byte_array<1>{{0x01}} + secret + hash, K);
    V = hmac_sha256_hash(V, K);

    while (true)
    {
        V = hmac_sha256_hash(V, K);

        if (verify_private_key(V))
            return V;

        K = hmac_sha256_hash(V + byte_array<1>{{0x00}}, K);
        V = hmac_sha256_hash(V, K);
    }
}
Esempio n. 4
0
/* parse_cryptserv_args()
 *
 * inputs	- parv parameters
 *		- parc count
 *		- info string (to be filled in by this routine)
 *		- key (to be filled in by this routine)
 * output	- NULL if invalid params, server name otherwise
 * side effects	- parv[2] is trimmed to HOSTLEN size if needed.
 */
static char *
parse_cryptserv_args(struct Client *client_p, char *parv[],
                     int parc, char *info, char *key)
{
  char *name;
  unsigned char *tmp, *out;
  int len;
  int decoded_len;

  info[0] = '\0';

  name = parv[2];

  /* parv[2] contains encrypted auth data */
  if (!(decoded_len = unbase64_block(&tmp, parv[3],
                                     strlen(parv[3]))))
  {
    cryptlink_error(client_p, "SERV",
                    "Couldn't base64 decode data",
                    NULL);
    return(NULL);
  }

  if (verify_private_key() == -1)
  {
    sendto_realops_flags(UMODE_ALL, L_ADMIN,
      "verify_private_key() returned -1.  Check log for information.");
  }

  if (ServerInfo.rsa_private_key == NULL)
  {
    cryptlink_error(client_p, "SERV", "No local private key found", NULL);
    return(NULL);
  }

  out = MyMalloc(RSA_size(ServerInfo.rsa_private_key));
  len = RSA_private_decrypt(decoded_len, tmp, out,
                            ServerInfo.rsa_private_key,
                            RSA_PKCS1_PADDING);

  MyFree(tmp);

  if (len < CIPHERKEYLEN)
  {
    report_crypto_errors();
    if (len < 0)
    {
      cryptlink_error(client_p, "AUTH", "Decryption failed", NULL);
    }
    else
    {
      cryptlink_error(client_p, "AUTH", "Not enough random data sent", NULL);
    }
    MyFree(out);
    return(NULL);
  }

  memcpy(key, out, CIPHERKEYLEN);
  MyFree(out);

  strlcpy(info, parv[4], REALLEN + 1);

  if (strlen(name) > HOSTLEN)
    name[HOSTLEN] = '\0';

  return(name);
}
Esempio n. 5
0
/*
 * cryptlink_auth - CRYPTLINK AUTH message handler
 *        parv[1] = secret key
 */
static void
cryptlink_auth(struct Client *client_p, struct Client *source_p,
               int parc, char *parv[])
{
  struct EncCapability *ecap;
  struct ConfItem *conf;
  struct AccessItem *aconf;
  int   enc_len;
  int   len;
  unsigned char *enc;
  unsigned char *key;

  if (parc < 4)
  {
    cryptlink_error(client_p, "AUTH", "Invalid params",
                    "CRYPTLINK AUTH - Invalid params");
    return;
  }

  if (!IsWaitAuth(client_p))
    return;

  for (ecap = CipherTable; ecap->name; ecap++)
  {
    if ((!irccmp(ecap->name, parv[2])) &&
        (IsCapableEnc(client_p, ecap->cap)))
    {
      client_p->localClient->in_cipher = ecap;
      break;
    }
  }

  if (client_p->localClient->in_cipher == NULL)
  {
    cryptlink_error(client_p, "AUTH", "Invalid cipher", "Invalid cipher");
    return;
  }

  if (!(enc_len = unbase64_block(&enc, parv[3], strlen(parv[3]))))
  {
    cryptlink_error(client_p, "AUTH",
                    "Could not base64 decode response",
                    "Malformed CRYPTLINK AUTH reply");
    return;
  }

  if (verify_private_key() == -1)
  {
    sendto_realops_flags(UMODE_ALL, L_ADMIN,
      "verify_private_key() returned -1.  Check log for information.");
  }

  key = MyMalloc(RSA_size(ServerInfo.rsa_private_key));
  len = RSA_private_decrypt(enc_len, (unsigned char *)enc,(unsigned char *)key,
                            ServerInfo.rsa_private_key,
                            RSA_PKCS1_PADDING);

  if (len < client_p->localClient->in_cipher->keylen)
  {
    report_crypto_errors();
    if (len < 0)
    {
      cryptlink_error(client_p, "AUTH",
                      "Decryption failed",
                      "Malformed CRYPTLINK AUTH reply");
    }
    else
    {
      cryptlink_error(client_p, "AUTH",
                      "Not enough random data sent",
                      "Malformed CRYPTLINK AUTH reply");
    }
    MyFree(enc);
    MyFree(key);
    return;
  }

  if (memcmp(key, client_p->localClient->in_key,
             client_p->localClient->in_cipher->keylen) != 0)
  {
    cryptlink_error(client_p, "AUTH",
                    "Unauthorized server connection attempt",
                    "Malformed CRYPTLINK AUTH reply");
    return;
  }

  conf = find_conf_name(&client_p->localClient->confs,
                         client_p->name, SERVER_TYPE);

  if (conf == NULL)
  {
    cryptlink_error(client_p, "AUTH",
                    "Lost C-line for server",
                    "Lost C-line");
    return;
  }

  aconf = (struct AccessItem *)map_to_conf(conf);

  if (!(client_p->localClient->out_cipher ||
      (client_p->localClient->out_cipher = check_cipher(client_p, aconf))))
  {
    cryptlink_error(client_p, "AUTH",
                    "Couldn't find compatible cipher",
                    "Couldn't find compatible cipher");
    return;
  }

  /* set hopcount */
  client_p->hopcount = 1;

  SetCryptIn(client_p);
  ClearWaitAuth(client_p);
  server_estab(client_p);
}