📄 hostkey_gcrypt.c
字号:
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 + -