+ len = RSA_size(cl->rsa_key);
+
+ /* Allocate buffers for the meta key */
+
+ buffer = xmalloc(len*2+1);
+
+ if(!cl->cipher_outkey)
+ cl->cipher_outkey = xmalloc(len);
+
+ if(!cl->cipher_outctx)
+ cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
+cp
+ /* Copy random data to the buffer */
+
+ RAND_bytes(cl->cipher_outkey, len);
+
+ /* The message we send must be smaller than the modulus of the RSA key.
+ By definition, for a key of k bits, the following formula holds:
+
+ 2^(k-1) <= modulus < 2^(k)
+
+ Where ^ means "to the power of", not "xor".
+ This means that to be sure, we must choose our message < 2^(k-1).
+ This can be done by setting the most significant bit to zero.
+ */
+
+ cl->cipher_outkey[0] &= 0x7F;
+
+ if(debug_lvl >= DEBUG_SCARY_THINGS)
+ {
+ bin2hex(cl->cipher_outkey, buffer, len);
+ buffer[len*2] = '\0';
+ syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
+ }
+
+ /* Encrypt the random data
+
+ We do not use one of the PKCS padding schemes here.
+ This is allowed, because we encrypt a totally random string
+ with a length equal to that of the modulus of the RSA key.
+ */
+
+ if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
+ {
+ syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
+ free(buffer);
+ return -1;
+ }
+cp
+ /* Convert the encrypted random data to a hexadecimal formatted string */
+
+ bin2hex(buffer, buffer, len);
+ buffer[len*2] = '\0';
+
+ /* Send the meta key */
+
+ x = send_request(cl, "%d %s", METAKEY, buffer);
+ free(buffer);
+
+ /* Further outgoing requests are encrypted with the key we just generated */
+
+ EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
+ cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
+ cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
+
+ cl->status.encryptout = 1;