X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcrypto_rsa.c;h=cbd9f8f372bc963940dbcca4385ce712914b3cf6;hb=35d61a3d33b90f7c1bb255e34b26a3b1cc5a3616;hp=edf1b2bdf1b306d53f38510ae43650d0ac21ed70;hpb=9dac7b6b7b035d55bdb9731795712ead92e11f76;p=oweals%2Fgnunet.git diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index edf1b2bdf..cbd9f8f37 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c @@ -186,43 +186,43 @@ key_from_sexp (gcry_mpi_t * array, /** * Extract the public key of the host. - * @param hostkey the hostkey to extract into the result. - * @param result where to write the result. + * @param priv the private key + * @param pub where to write the public key */ void GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey - *hostkey, + *priv, struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded - *result) + *pub) { gcry_mpi_t skey[2]; size_t size; int rc; - rc = key_from_sexp (skey, hostkey->sexp, "public-key", "ne"); + rc = key_from_sexp (skey, priv->sexp, "public-key", "ne"); if (rc) - rc = key_from_sexp (skey, hostkey->sexp, "private-key", "ne"); + rc = key_from_sexp (skey, priv->sexp, "private-key", "ne"); if (rc) - rc = key_from_sexp (skey, hostkey->sexp, "rsa", "ne"); + rc = key_from_sexp (skey, priv->sexp, "rsa", "ne"); GNUNET_assert (0 == rc); - result->len = + pub->len = htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - - sizeof (result->padding)); - result->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); - result->padding = 0; + sizeof (pub->padding)); + pub->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); + pub->padding = 0; size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, - &result->key[0], size, &size, skey[0])); - adjust (&result->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); + &pub->key[0], size, &size, skey[0])); + adjust (&pub->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); size = GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, - &result->key + &pub->key [GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size, &size, skey[1])); - adjust (&result->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size, + adjust (&pub->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size, GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); gcry_mpi_release (skey[0]); @@ -559,24 +559,22 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding) struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) { -#ifndef MINGW - // FIXME NILS - struct flock fl; -#endif struct GNUNET_CRYPTO_RsaPrivateKey *ret; struct RsaPrivateKeyBinaryEncoded *enc; - struct stat sbuf; uint16_t len; - int fd; + struct GNUNET_DISK_FileHandle *fd; unsigned int cnt; int ec; + uint64_t fs; if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) return NULL; - while (0 != STAT (filename, &sbuf)) + while (GNUNET_YES != GNUNET_DISK_file_test (filename)) { - fd = open (filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (-1 == fd) + fd = GNUNET_DISK_file_open (filename, + GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS, + GNUNET_DISK_PERM_USER_READ| GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_READ); + if (NULL == fd) { if (errno == EEXIST) continue; @@ -584,58 +582,42 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) "open", filename); return NULL; } -#ifndef MINGW - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); cnt = 0; - while (0 != fcntl (fd, F_SETLK, &fl)) + while (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct RsaPrivateKeyBinaryEncoded), GNUNET_YES)) { sleep (1); if (0 == ++cnt % 10) { ec = errno; - fl.l_type = F_GETLK; - fcntl (fd, F_GETLK, &fl); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ - ("Could not aquire lock on file `%s' due to process %u: %s...\n"), - filename, fl.l_pid, STRERROR (ec)); + ("Could not aquire lock on file `%s': %s...\n"), + filename, STRERROR (ec)); } - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); } -#endif GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Creating a new private key. This may take a while.\n")); ret = GNUNET_CRYPTO_rsa_key_create (); GNUNET_assert (ret != NULL); enc = rsa_encode_key (ret); GNUNET_assert (enc != NULL); - GNUNET_assert (ntohs (enc->len) == WRITE (fd, enc, ntohs (enc->len))); + GNUNET_assert (ntohs (enc->len) == GNUNET_DISK_file_write (fd, enc, ntohs (enc->len))); GNUNET_free (enc); -#ifndef MINGW - fdatasync (fd); - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); - if (0 != fcntl (fd, F_SETLK, &fl)) + + GNUNET_DISK_file_sync (fd); + if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct RsaPrivateKeyBinaryEncoded))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); -#endif - GNUNET_assert (0 == CLOSE (fd)); + GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Stored new private key in `%s'.\n"), filename); return ret; } /* hostkey file exists already, read it! */ - fd = open (filename, O_RDONLY); - if (-1 == fd) + fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_NONE); + if (NULL == fd) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename); return NULL; @@ -643,22 +625,14 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) cnt = 0; while (1) { -#ifndef MINGW - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_RDLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); - if (0 != fcntl (fd, F_SETLK, &fl)) + if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct RsaPrivateKeyBinaryEncoded), GNUNET_NO)) { if (0 == ++cnt % 10) { ec = errno; - fl.l_type = F_GETLK; - fcntl (fd, F_GETLK, &fl); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Could not aquire lock on file `%s' due to process %u: %s...\n"), - filename, fl.l_pid, STRERROR (ec)); + _("Could not aquire lock on file `%s': %s...\n"), + filename, STRERROR (ec)); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("This may be ok if someone is currently generating a hostkey.\n")); @@ -666,34 +640,25 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) sleep (1); continue; } -#endif - if (0 != STAT (filename, &sbuf)) + if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { /* eh, what!? File we opened is now gone!? */ - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename); -#ifndef MINGW - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); - if (0 != fcntl (fd, F_SETLK, &fl)) + if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct RsaPrivateKeyBinaryEncoded))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); - GNUNET_assert (0 == CLOSE (fd)); -#endif + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); + return NULL; } - if (sbuf.st_size < sizeof (struct RsaPrivateKeyBinaryEncoded)) + if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES)) + fs = 0; + if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded)) { -#ifndef MINGW /* maybe we got the read lock before the hostkey generating process had a chance to get the write lock; give it up! */ - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); - if (0 != fcntl (fd, F_SETLK, &fl)) + if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct RsaPrivateKeyBinaryEncoded))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); if (0 == ++cnt % 10) @@ -701,7 +666,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"), - filename, (unsigned int) sbuf.st_size, + filename, (unsigned int) fs, (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded)); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -710,15 +675,14 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) } sleep (2); /* wait a bit longer! */ continue; -#endif } break; } - enc = GNUNET_malloc (sbuf.st_size); - GNUNET_assert (sbuf.st_size == READ (fd, enc, sbuf.st_size)); + enc = GNUNET_malloc (fs); + GNUNET_assert (fs == GNUNET_DISK_file_read (fd, enc, fs)); len = ntohs (enc->len); ret = NULL; - if ((len != sbuf.st_size) || (NULL == (ret = rsa_decode_key (enc)))) + if ((len != fs) || (NULL == (ret = rsa_decode_key (enc)))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ @@ -726,15 +690,9 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) filename); } GNUNET_free (enc); -#ifndef MINGW - memset (&fl, 0, sizeof (struct flock)); - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); - if (0 != fcntl (fd, F_SETLK, &fl)) + if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct RsaPrivateKeyBinaryEncoded))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); -#endif - GNUNET_assert (0 == CLOSE (fd)); + GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); return ret; } @@ -751,7 +709,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) */ int GNUNET_CRYPTO_rsa_encrypt (const void *block, - uint16_t size, + size_t size, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey, struct GNUNET_CRYPTO_RsaEncryptedData *target) @@ -792,17 +750,18 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, /** * Decrypt a given block with the hostkey. * - * @param hostkey the hostkey with which to decrypt this block + * @param key the key 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 + * @return the size of the decrypted block, -1 on error */ -int -GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey, +ssize_t +GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_CRYPTO_RsaEncryptedData *block, - void *result, uint16_t max) + void *result, + size_t max) { gcry_sexp_t resultsexp; gcry_sexp_t data; @@ -813,7 +772,7 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey, unsigned char *tmp; #if EXTRA_CHECKS - GNUNET_assert (0 == gcry_pk_testkey (hostkey->sexp)); + GNUNET_assert (0 == gcry_pk_testkey (key->sexp)); #endif size = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData); GNUNET_assert (0 == gcry_mpi_scan (&val, @@ -823,7 +782,7 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey, gcry_sexp_build (&data, &erroff, "(enc-val(flags)(rsa(a %m)))", val)); gcry_mpi_release (val); - GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, hostkey->sexp)); + GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, key->sexp)); gcry_sexp_release (data); /* resultsexp has format "(value %m)" */ GNUNET_assert (NULL != @@ -846,13 +805,13 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey, /** * Sign a given block. * - * @param hostkey private key to use for the signing + * @param key private key to use for the signing * @param purpose what to sign (size, purpose) - * @param result where to write the signature + * @param sig where to write the signature * @return GNUNET_SYSERR on error, GNUNET_OK on success */ int -GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey, +GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_CRYPTO_RsaSignaturePurpose *purpose, struct GNUNET_CRYPTO_RsaSignature *sig) { @@ -876,7 +835,7 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey, - 1], &hc, sizeof (GNUNET_HashCode)); GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); GNUNET_free (buff); - GNUNET_assert (0 == gcry_pk_sign (&result, data, hostkey->sexp)); + GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp)); gcry_sexp_release (data); GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "s")); gcry_sexp_release (result);