+int send_metakey(connection_t *cl)
+{
+ char *buffer;
+ int len, x;
+cp
+ 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);
+
+ cl->cipher_outkey[0] &= 0x7F; /* FIXME: Somehow if the first byte is more than 0xD0 or something like that, decryption fails... */
+
+ 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 */
+
+ if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len) /* NO_PADDING because the message size equals the RSA key size and it is totally random */
+ {
+ 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 */
+
+ if(cl->status.outgoing)
+ cl->allow_request = METAKEY;
+ else
+ cl->allow_request = ACK;
+
+ x = send_request(cl, "%d %s", METAKEY, buffer);
+ free(buffer);
+
+ EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(), cl->cipher_outkey, cl->cipher_outkey + EVP_bf_cfb()->key_len);
+cp
+ return x;
+}
+
+int metakey_h(connection_t *cl)