⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostkey_gcrypt.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
                      GCRYMPI_FMT_USG,                      &((const unsigned char *) (&encoding[1]))[pos],                      size, &size);  pos += ntohs (encoding->sized);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);      gcry_mpi_release (n);      gcry_mpi_release (e);      GNUNET_unlock_gcrypt_ ();      return NULL;    }  /* swap p and q! */  size = ntohs (encoding->sizep);  if (size > 0)    {      rc = gcry_mpi_scan (&q,                          GCRYMPI_FMT_USG,                          &((const unsigned char *) (&encoding[1]))[pos],                          size, &size);      pos += ntohs (encoding->sizep);      if (rc)        {          LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);          gcry_mpi_release (n);          gcry_mpi_release (e);          gcry_mpi_release (d);          GNUNET_unlock_gcrypt_ ();          return NULL;        }    }  else    q = NULL;  size = ntohs (encoding->sizeq);  if (size > 0)    {      rc = gcry_mpi_scan (&p,                          GCRYMPI_FMT_USG,                          &((const unsigned char *) (&encoding[1]))[pos],                          size, &size);      pos += ntohs (encoding->sizeq);      if (rc)        {          LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);          gcry_mpi_release (n);          gcry_mpi_release (e);          gcry_mpi_release (d);          if (q != NULL)            gcry_mpi_release (q);          GNUNET_unlock_gcrypt_ ();          return NULL;        }    }  else    p = NULL;  pos += ntohs (encoding->sizedmp1);  pos += ntohs (encoding->sizedmq1);  size = ntohs (encoding->len) - sizeof (GNUNET_RSA_PrivateKeyEncoded) - pos;  if (size > 0)    {      rc = gcry_mpi_scan (&u,                          GCRYMPI_FMT_USG,                          &((const unsigned char *) (&encoding[1]))[pos],                          size, &size);      if (rc)        {          LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);          gcry_mpi_release (n);          gcry_mpi_release (e);          gcry_mpi_release (d);          if (p != NULL)            gcry_mpi_release (p);          if (q != NULL)            gcry_mpi_release (q);          GNUNET_unlock_gcrypt_ ();          return NULL;        }    }  else    u = NULL;  if ((p != NULL) && (q != NULL) && (u != NULL))    {      rc = gcry_sexp_build (&res, &size,        /* erroff */                            "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",                            n, e, d, p, q, u);    }  else    {      if ((p != NULL) && (q != NULL))        {          rc = gcry_sexp_build (&res, &size,    /* erroff */                                "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",                                n, e, d, p, q);        }      else        {          rc = gcry_sexp_build (&res, &size,    /* erroff */                                "(private-key(rsa(n %m)(e %m)(d %m)))",                                n, e, d);        }    }  gcry_mpi_release (n);  gcry_mpi_release (e);  gcry_mpi_release (d);  if (p != NULL)    gcry_mpi_release (p);  if (q != NULL)    gcry_mpi_release (q);  if (u != NULL)    gcry_mpi_release (u);  if (rc)    LOG_GCRY (NULL, LOG_ERROR, "gcry_sexp_build", rc);#if EXTRA_CHECKS  if (gcry_pk_testkey (res))    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_pk_testkey", rc);      GNUNET_unlock_gcrypt_ ();      return NULL;    }#endif  ret = GNUNET_malloc (sizeof (struct GNUNET_RSA_PrivateKey));  ret->sexp = res;  GNUNET_unlock_gcrypt_ ();  return ret;}/** * Encrypt a block with the public key of another host that uses the * same cyper. * * @param block the block to encrypt * @param size the size of block * @param publicKey the encoded public key used to encrypt * @param target where to store the encrypted block * @returns GNUNET_SYSERR on error, GNUNET_OK if ok */intGNUNET_RSA_encrypt (const void *block,                    unsigned short size,                    const GNUNET_RSA_PublicKey * publicKey,                    GNUNET_RSA_EncryptedData * target){  gcry_sexp_t result;  gcry_sexp_t data;  struct GNUNET_RSA_PrivateKey *pubkey;  gcry_mpi_t val;  gcry_mpi_t rval;  size_t isize;  size_t erroff;  int rc;  GNUNET_GE_ASSERT (NULL, size <= sizeof (GNUNET_HashCode));  pubkey = public2PrivateKey (publicKey);  isize = size;  GNUNET_lock_gcrypt_ ();  rc = gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);      GNUNET_RSA_free_key (pubkey);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = gcry_sexp_build (&data,                        &erroff, "(data (flags pkcs1)(value %m))", val);  gcry_mpi_release (val);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_sexp_build", rc);        /* more info in erroff */      GNUNET_RSA_free_key (pubkey);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = gcry_pk_encrypt (&result, data, pubkey->sexp);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_pk_encrypt", rc);      gcry_sexp_release (data);      GNUNET_RSA_free_key (pubkey);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  gcry_sexp_release (data);  GNUNET_RSA_free_key (pubkey);  rc = key_from_sexp (&rval, result, "rsa", "a");  gcry_sexp_release (result);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "key_from_sexp", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  isize = sizeof (GNUNET_RSA_EncryptedData);  rc = gcry_mpi_print (GCRYMPI_FMT_USG,                       (unsigned char *) target, isize, &isize, rval);  gcry_mpi_release (rval);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_print", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  adjust (&target->encoding[0], isize, sizeof (GNUNET_RSA_EncryptedData));  GNUNET_unlock_gcrypt_ ();  return GNUNET_OK;}/** * Decrypt a given block with the hostkey. * * @param hostkey the hostkey with which to decrypt this block * @param block the data to decrypt, encoded as returned by encrypt * @param result pointer to a location where the result can be stored * @param max the maximum number of bits to store for the result, if *        the decrypted block is bigger, an error is returned * @returns the size of the decrypted block, -1 on error */intGNUNET_RSA_decrypt (const struct GNUNET_RSA_PrivateKey *hostkey,                    const GNUNET_RSA_EncryptedData * block,                    void *result, unsigned short max){  gcry_sexp_t resultsexp;  gcry_sexp_t data;  size_t erroff;  size_t size;  gcry_mpi_t val;  int rc;  unsigned char *endp;  unsigned char *tmp;  GNUNET_lock_gcrypt_ ();#if EXTRA_CHECKS  rc = gcry_pk_testkey (hostkey->sexp);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_pk_testkey", rc);      GNUNET_unlock_gcrypt_ ();      return -1;    }#endif  size = sizeof (GNUNET_RSA_EncryptedData);  rc = gcry_mpi_scan (&val,                      GCRYMPI_FMT_USG, &block->encoding[0], size, &size);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = gcry_sexp_build (&data, &erroff, "(enc-val(flags)(rsa(a %m)))", val);  gcry_mpi_release (val);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_sexp_build", rc);        /* more info in erroff */      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = gcry_pk_decrypt (&resultsexp, data, hostkey->sexp);  gcry_sexp_release (data);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_pk_decrypt", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  /* resultsexp has format "(value %m)" */  val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG);  gcry_sexp_release (resultsexp);  if (val == NULL)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_sexp_nth_mpi", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8);  size = max + HOSTKEY_LEN / 8;  rc = gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val);  gcry_mpi_release (val);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_print", rc);      GNUNET_free (tmp);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  endp = tmp;  endp += (size - max);  size = max;  memcpy (result, endp, size);  GNUNET_free (tmp);  GNUNET_unlock_gcrypt_ ();  return size;}/** * Sign a given block. * * @param hostkey the hostkey with which to GNUNET_RSA_sign this block * @param size how many bytes to GNUNET_RSA_sign * @param block the data to GNUNET_RSA_sign * @param sig where to write the signature * @return GNUNET_SYSERR on error, GNUNET_OK on success */intGNUNET_RSA_sign (const struct GNUNET_RSA_PrivateKey *hostkey,                 unsigned short size, const void *block,                 GNUNET_RSA_Signature * sig){  gcry_sexp_t result;  gcry_sexp_t data;  size_t ssize;  gcry_mpi_t rval;  GNUNET_HashCode hc;  char *buff;  int bufSize;  int rc;  GNUNET_hash (block, size, &hc);#define FORMATSTRING "(4:data(5:flags5:pkcs1)(4:hash6:sha51264:0123456789012345678901234567890123456789012345678901234567890123))"  bufSize = strlen (FORMATSTRING) + 1;  buff = GNUNET_malloc (bufSize);  memcpy (buff, FORMATSTRING, bufSize);  memcpy (&buff          [bufSize -           strlen           ("0123456789012345678901234567890123456789012345678901234567890123))")           - 1], &hc, sizeof (GNUNET_HashCode));  GNUNET_lock_gcrypt_ ();  rc = gcry_sexp_new (&data, buff, bufSize, 0);  GNUNET_free (buff);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_sexp_new", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = gcry_pk_sign (&result, data, hostkey->sexp);  gcry_sexp_release (data);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_pk_sign", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = key_from_sexp (&rval, result, "rsa", "s");  gcry_sexp_release (result);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "key_from_sexp", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  ssize = sizeof (GNUNET_RSA_Signature);  rc = gcry_mpi_print (GCRYMPI_FMT_USG,                       (unsigned char *) sig, ssize, &ssize, rval);  gcry_mpi_release (rval);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_print", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  adjust (&sig->sig[0], ssize, sizeof (GNUNET_RSA_Signature));  GNUNET_unlock_gcrypt_ ();  return GNUNET_OK;}/** * Verify signature. * * @param block the signed data * @param len the length of the block * @param sig signature * @param publicKey public key of the signer * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid */intGNUNET_RSA_verify (const void *block,                   unsigned short len,                   const GNUNET_RSA_Signature * sig,                   const GNUNET_RSA_PublicKey * publicKey){  gcry_sexp_t data;  gcry_sexp_t sigdata;  size_t size;  gcry_mpi_t val;  struct GNUNET_RSA_PrivateKey *hostkey;  GNUNET_HashCode hc;  char *buff;  int bufSize;  size_t erroff;  int rc;  size = sizeof (GNUNET_RSA_Signature);  GNUNET_lock_gcrypt_ ();  rc = gcry_mpi_scan (&val,                      GCRYMPI_FMT_USG,                      (const unsigned char *) sig, size, &size);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_mpi_scan", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  rc = gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))", val);  gcry_mpi_release (val);  if (rc)    {      LOG_GCRY (NULL, LOG_ERROR, "gcry_sexp_build", rc);      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  GNUNET_hash (block, len, &hc);  bufSize = strlen (FORMATSTRING) + 1;  buff = GNUNET_malloc (bufSize);  memcpy (buff, FORMATSTRING, bufSize);  memcpy (&buff[strlen (FORMATSTRING) -                strlen                ("0123456789012345678901234567890123456789012345678901234567890123))")],          &hc, sizeof (GNUNET_HashCode));  rc = gcry_sexp_new (&data, buff, bufSize, 0);  GNUNET_free (buff);  hostkey = public2PrivateKey (publicKey);  if (hostkey == NULL)    {      gcry_sexp_release (data);      gcry_sexp_release (sigdata);      return GNUNET_SYSERR;    }  rc = gcry_pk_verify (sigdata, data, hostkey->sexp);  GNUNET_RSA_free_key (hostkey);  gcry_sexp_release (data);  gcry_sexp_release (sigdata);  if (rc)    {      GNUNET_GE_LOG (NULL,                     GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK |                     GNUNET_GE_DEVELOPER,                     _("RSA signature verification failed at %s:%d: %s\n"),                     __FILE__, __LINE__, gcry_strerror (rc));      GNUNET_unlock_gcrypt_ ();      return GNUNET_SYSERR;    }  else    {      GNUNET_unlock_gcrypt_ ();      return GNUNET_OK;    }}/* end of hostkey_gcrypt.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -