X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcrypto_rsa.c;h=b5a8c85dea590ace3e46ee54e555276fbb4ae80f;hb=9b0414d6f98f33d7e1c33dafe105eb58da0bf79b;hp=d4b87d3c9bbac8e7afe3a1835b81fe8b0bd34c11;hpb=2529c7df1df2f22d5c0edae89271be657c6d1620;p=oweals%2Fgnunet.git diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index d4b87d3c9..b5a8c85de 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c @@ -79,14 +79,15 @@ adjust (unsigned char *buf, size_t size, size_t target) /** - * Free memory occupied by hostkey - * @param hostkey pointer to the memory to free + * Free memory occupied by RSA private key. + * + * @param key pointer to the memory to free */ void -GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) +GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key) { - gcry_sexp_release (hostkey->sexp); - GNUNET_free (hostkey); + gcry_sexp_release (key->sexp); + GNUNET_free (key); } @@ -109,8 +110,7 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, unsigned int i; unsigned int idx; - list = gcry_sexp_find_token (sexp, topname, 0); - if (! list) + if (! (list = gcry_sexp_find_token (sexp, topname, 0))) return 1; l2 = gcry_sexp_cadr (list); gcry_sexp_release (list); @@ -120,8 +120,7 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, idx = 0; for (s = elems; *s; s++, idx++) { - l2 = gcry_sexp_find_token (list, s, 1); - if (! l2) + if (! (l2 = gcry_sexp_find_token (list, s, 1))) { for (i = 0; i < idx; i++) { @@ -151,6 +150,7 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, /** * Extract the public key of the host. + * * @param priv the private key * @param pub where to write the public key */ @@ -165,9 +165,9 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey int rc; rc = key_from_sexp (skey, priv->sexp, "public-key", "ne"); - if (rc) + if (0 != rc) rc = key_from_sexp (skey, priv->sexp, "private-key", "ne"); - if (rc) + if (0 != rc) rc = key_from_sexp (skey, priv->sexp, "rsa", "ne"); GNUNET_assert (0 == rc); pub->len = @@ -259,16 +259,15 @@ GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc, /** - * Internal: publicKey => RSA-Key. + * Convert the given public key from the network format to the + * S-expression that can be used by libgcrypt. * - * Note that the return type is not actually a private - * key but rather an sexpression for the public key! + * @param publicKey public key to decode + * @return NULL on error */ -static struct GNUNET_CRYPTO_RsaPrivateKey * -public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded - *publicKey) +static gcry_sexp_t +decode_public_key (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) { - struct GNUNET_CRYPTO_RsaPrivateKey *ret; gcry_sexp_t result; gcry_mpi_t n; gcry_mpi_t e; @@ -285,17 +284,15 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded return NULL; } size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; - rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size); - if (rc) + if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size))) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); return NULL; } size = GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; - rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG, - &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], - size, &size); - if (rc) + if (0 != (rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG, + &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], + size, &size))) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (n); @@ -305,21 +302,20 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded e); gcry_mpi_release (n); gcry_mpi_release (e); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ return NULL; } - ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); - ret->sexp = result; - return ret; + return result; } /** * Encode the private key in a format suitable for * storing it into a file. - * @returns encoding of the private key. + * + * @return encoding of the private key. * The first 4 bytes give the size of the array, as usual. */ struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * @@ -357,7 +353,7 @@ GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) size = sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded); for (i = 0; i < 6; i++) { - if (pkv[i] != NULL) + if (NULL != pkv[i]) { GNUNET_assert (0 == gcry_mpi_aprint (GCRYMPI_FMT_USG, @@ -411,6 +407,7 @@ GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) * * @param buf the buffer where the private key data is stored * @param len the length of the data in 'buffer' + * @return NULL on error */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) @@ -419,11 +416,17 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *encoding = (const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *) buf; gcry_sexp_t res; - gcry_mpi_t n, e, d, p, q, u; + gcry_mpi_t n; + gcry_mpi_t e; + gcry_mpi_t d; + gcry_mpi_t p; + gcry_mpi_t q; + gcry_mpi_t u; int rc; size_t size; - int pos; + size_t pos; uint16_t enc_len; + size_t erroff; enc_len = ntohs (encoding->len); if (len != enc_len) @@ -435,7 +438,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) &((const unsigned char *) (&encoding[1]))[pos], size, &size); pos += ntohs (encoding->sizen); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); return NULL; @@ -445,7 +448,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) &((const unsigned char *) (&encoding[1]))[pos], size, &size); pos += ntohs (encoding->sizee); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (n); @@ -456,7 +459,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) &((const unsigned char *) (&encoding[1]))[pos], size, &size); pos += ntohs (encoding->sized); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (n); @@ -471,7 +474,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) &((const unsigned char *) (&encoding[1]))[pos], size, &size); pos += ntohs (encoding->sizep); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (n); @@ -489,13 +492,13 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) &((const unsigned char *) (&encoding[1]))[pos], size, &size); pos += ntohs (encoding->sizeq); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (n); gcry_mpi_release (e); gcry_mpi_release (d); - if (q != NULL) + if (NULL != q) gcry_mpi_release (q); return NULL; } @@ -511,15 +514,15 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG, &((const unsigned char *) (&encoding[1]))[pos], size, &size); - if (rc) + if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); gcry_mpi_release (n); gcry_mpi_release (e); gcry_mpi_release (d); - if (p != NULL) + if (NULL != p) gcry_mpi_release (p); - if (q != NULL) + if (NULL != q) gcry_mpi_release (q); return NULL; } @@ -527,40 +530,40 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) else u = NULL; - if ((p != NULL) && (q != NULL) && (u != NULL)) + if ((NULL != p) && (NULL != q) && (NULL != u)) { - rc = gcry_sexp_build (&res, &size, /* erroff */ + rc = gcry_sexp_build (&res, &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)) + if ((NULL != p) && (NULL != q)) { - rc = gcry_sexp_build (&res, &size, /* erroff */ + rc = gcry_sexp_build (&res, &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 */ + rc = gcry_sexp_build (&res, &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) + if (NULL != p) gcry_mpi_release (p); - if (q != NULL) + if (NULL != q) gcry_mpi_release (q); - if (u != NULL) + if (NULL != u) gcry_mpi_release (u); - if (rc) + if (0 != rc) LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); #if EXTRA_CHECKS - if (gcry_pk_testkey (res)) + if (0 != (rc = gcry_pk_testkey (res))) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); return NULL; @@ -725,7 +728,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) GNUNET_DISK_PERM_USER_WRITE); if (NULL == fd) { - if (errno == EEXIST) + if (EEXIST == errno) { if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { @@ -775,9 +778,6 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); - LOG (GNUNET_ERROR_TYPE_INFO, - _("I am host `%s'. Stored new private key in `%s'.\n"), - GNUNET_i2s (&pid), filename); return ret; } /* hostkey file exists already, read it! */ @@ -804,7 +804,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) STRERROR (ec)); LOG (GNUNET_ERROR_TYPE_ERROR, _ - ("This may be ok if someone is currently generating a hostkey.\n")); + ("This may be ok if someone is currently generating a private key.\n")); } short_wait (); continue; @@ -825,7 +825,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) fs = 0; if (fs < sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)) { - /* maybe we got the read lock before the hostkey generating + /* maybe we got the read lock before the key generating * process had a chance to get the write lock; give it up! */ if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, @@ -835,12 +835,12 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) { LOG (GNUNET_ERROR_TYPE_ERROR, _ - ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"), + ("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"), filename, (unsigned int) fs, (unsigned int) sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)); LOG (GNUNET_ERROR_TYPE_ERROR, _ - ("This may be ok if someone is currently generating a hostkey.\n")); + ("This may be ok if someone is currently generating a private key.\n")); } short_wait (); /* wait a bit longer! */ continue; @@ -872,9 +872,6 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) { GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); - LOG (GNUNET_ERROR_TYPE_INFO, - _("I am host `%s'. Read private key from `%s'.\n"), GNUNET_i2s (&pid), - filename); } return ret; } @@ -1102,15 +1099,15 @@ GNUNET_CRYPTO_rsa_key_create_stop (struct GNUNET_CRYPTO_RsaKeyGenerationContext /** - * Setup a hostkey file for a peer given the name of the + * Setup a key file for a peer given the name of the * configuration file (!). This function is used so that * at a later point code can be certain that reading a - * hostkey is fast (for example in time-dependent testcases). + * key is fast (for example in time-dependent testcases). * * @param cfg_name name of the configuration file to use */ void -GNUNET_CRYPTO_setup_hostkey (const char *cfg_name) +GNUNET_CRYPTO_rsa_setup_hostkey (const char *cfg_name) { struct GNUNET_CONFIGURATION_Handle *cfg; struct GNUNET_CRYPTO_RsaPrivateKey *pk; @@ -1148,15 +1145,14 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, { gcry_sexp_t result; gcry_sexp_t data; - struct GNUNET_CRYPTO_RsaPrivateKey *pubkey; + gcry_sexp_t psexp; gcry_mpi_t val; gcry_mpi_t rval; size_t isize; size_t erroff; GNUNET_assert (size <= sizeof (struct GNUNET_HashCode)); - pubkey = public2PrivateKey (publicKey); - if (pubkey == NULL) + if (! (psexp = decode_public_key (publicKey))) return GNUNET_SYSERR; isize = size; GNUNET_assert (0 == @@ -1165,10 +1161,9 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, gcry_sexp_build (&data, &erroff, "(data (flags pkcs1)(value %m))", val)); gcry_mpi_release (val); - GNUNET_assert (0 == gcry_pk_encrypt (&result, data, pubkey->sexp)); + GNUNET_assert (0 == gcry_pk_encrypt (&result, data, psexp)); gcry_sexp_release (data); - GNUNET_CRYPTO_rsa_key_free (pubkey); - + gcry_sexp_release (psexp); GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "a")); gcry_sexp_release (result); isize = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData); @@ -1183,7 +1178,7 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, /** - * Decrypt a given block with the hostkey. + * Decrypt a given block with the key. * * @param key the key with which to decrypt this block * @param block the data to decrypt, encoded as returned by encrypt @@ -1235,6 +1230,39 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key, } +/** + * Convert the data specified in the given purpose argument to an + * S-expression suitable for signature operations. + * + * @param purpose data to convert + * @return converted s-expression + */ +static gcry_sexp_t +data_to_pkcs1 (const struct GNUNET_CRYPTO_RsaSignaturePurpose *purpose) +{ + struct GNUNET_HashCode hc; + size_t bufSize; + gcry_sexp_t data; + + GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); +#define FORMATSTRING "(4:data(5:flags5:pkcs1)(4:hash6:sha51264:0123456789012345678901234567890123456789012345678901234567890123))" + bufSize = strlen (FORMATSTRING) + 1; + { + char buff[bufSize]; + + memcpy (buff, FORMATSTRING, bufSize); + memcpy (&buff + [bufSize - + strlen + ("0123456789012345678901234567890123456789012345678901234567890123))") + - 1], &hc, sizeof (struct GNUNET_HashCode)); + GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); + } +#undef FORMATSTRING + return data; +} + + /** * Sign a given block. * @@ -1252,22 +1280,8 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, gcry_sexp_t data; size_t ssize; gcry_mpi_t rval; - struct GNUNET_HashCode hc; - char *buff; - int bufSize; - GNUNET_CRYPTO_hash (purpose, ntohl (purpose->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 (struct GNUNET_HashCode)); - GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); - GNUNET_free (buff); + data = data_to_pkcs1 (purpose); GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp)); gcry_sexp_release (data); GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "s")); @@ -1303,16 +1317,12 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose, gcry_sexp_t sigdata; size_t size; gcry_mpi_t val; - struct GNUNET_CRYPTO_RsaPrivateKey *hostkey; - struct GNUNET_HashCode hc; - char *buff; - int bufSize; + gcry_sexp_t psexp; size_t erroff; int rc; if (purpose != ntohl (validate->purpose)) return GNUNET_SYSERR; /* purpose mismatch */ - GNUNET_CRYPTO_hash (validate, ntohl (validate->size), &hc); size = sizeof (struct GNUNET_CRYPTO_RsaSignature); GNUNET_assert (0 == gcry_mpi_scan (&val, GCRYMPI_FMT_USG, @@ -1321,25 +1331,15 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose, gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))", val)); gcry_mpi_release (val); - bufSize = strlen (FORMATSTRING) + 1; - buff = GNUNET_malloc (bufSize); - memcpy (buff, FORMATSTRING, bufSize); - memcpy (&buff - [strlen (FORMATSTRING) - - strlen - ("0123456789012345678901234567890123456789012345678901234567890123))")], - &hc, sizeof (struct GNUNET_HashCode)); - GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); - GNUNET_free (buff); - hostkey = public2PrivateKey (publicKey); - if (hostkey == NULL) + data = data_to_pkcs1 (validate); + if (! (psexp = decode_public_key (publicKey))) { gcry_sexp_release (data); gcry_sexp_release (sigdata); return GNUNET_SYSERR; } - rc = gcry_pk_verify (sigdata, data, hostkey->sexp); - GNUNET_CRYPTO_rsa_key_free (hostkey); + rc = gcry_pk_verify (sigdata, data, psexp); + gcry_sexp_release (psexp); gcry_sexp_release (data); gcry_sexp_release (sigdata); if (rc)