Exemplo n.º 1
0
EAPI Eina_Bool
evas_cserve_mem_resize(Mem *m, int size)
{
   if (m->size == size) return 1;
   if (m->write)
     {
        if (ftruncate(m->fd, size) < 0) return 0;
        munmap(m->data, m->size);
        eina_mmap_safety_enabled_set(EINA_TRUE);
        m->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, m->fd, 0);
     }
   else
     {
        munmap(m->data, m->size);
        eina_mmap_safety_enabled_set(EINA_TRUE);
        m->data = mmap(NULL, size, PROT_READ, MAP_SHARED, m->fd, 0);
     }
   if (m->data == MAP_FAILED)
     {
        m->data = NULL;
        return 0;
     }
   m->size = size;
   return 1;
}
Exemplo n.º 2
0
EAPI Mem *
evas_cserve_mem_new(int size, const char *name)
{
   Mem *m;
   static int id = 0;
   char buf[PATH_MAX];

   m = calloc(1, sizeof(Mem));
   if (!m) return NULL;
   if (name)
     snprintf(buf, sizeof(buf), "/evas-shm-%x.%s", getuid(), name);
   else
     {
        id++;
        snprintf(buf, sizeof(buf), "/evas-shm-%x.%x.%x", getuid(), getpid(), id);
     }
   m->id = id;
   m->offset = 0;
   m->name = strdup(buf);
   if (!m->name)
     {
        free(m);
        return NULL;
     }
   m->size = size;
   m->fd = shm_open(m->name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
   if (m->fd < 0)
     {
        free(m->name);
        free(m);
        return NULL;
     }
   if (ftruncate(m->fd, m->size) < 0)
     {
        shm_unlink(m->name);
        close(m->fd);
        free(m->name);
        free(m);
        return NULL;
     }

   eina_mmap_safety_enabled_set(EINA_TRUE);

   m->data = mmap(NULL, m->size, PROT_READ | PROT_WRITE, MAP_SHARED, m->fd, 0);
   if (m->data == MAP_FAILED)
     {
        shm_unlink(m->name);
        close(m->fd);
        free(m->name);
        free(m);
        return NULL;
     }
   m->ref = 1;
   m->write = 1;
   return m;
}
Exemplo n.º 3
0
void 
_evas_xcb_xdefaults_init(void) 
{
   char buff[PATH_MAX];

   snprintf(buff, sizeof(buff), "%s/.Xdefaults", getenv("HOME"));
   if ((_evas_xcb_xdefaults_file = eina_file_open(buff, EINA_FALSE)))
     {
        eina_mmap_safety_enabled_set(EINA_TRUE);

        _evas_xcb_xdefaults_data = 
          eina_file_map_all(_evas_xcb_xdefaults_file, EINA_FILE_SEQUENTIAL);
     }
}
Exemplo n.º 4
0
EAPI Mem *
evas_cserve_mem_open(int pid, int id, const char *name, int size, int do_write)
{
   Mem *m;
   char buf[PATH_MAX];

   m = calloc(1, sizeof(Mem));
   if (!m) return NULL;
   if (name)
     snprintf(buf, sizeof(buf), "/evas-shm-%x.%s", getuid(), name);
   else
     snprintf(buf, sizeof(buf), "/evas-shm-%x.%x.%x", getuid(), pid, id);
   m->name = strdup(buf);
   if (!m->name)
     {
        free(m);
        return NULL;
     }
   m->size = size;
   if (do_write)
     m->fd = shm_open(m->name, O_RDWR, S_IRUSR | S_IWUSR);
   else
     m->fd = shm_open(m->name, O_RDONLY, S_IRUSR);
   if (m->fd < 0)
     {
        free(m->name);
        free(m);
        return NULL;
     }
   m->write = do_write;

   eina_mmap_safety_enabled_set(EINA_TRUE);

   if (do_write)
     m->data = mmap(NULL, m->size, PROT_READ | PROT_WRITE, MAP_SHARED, m->fd, 0);
   else
     m->data = mmap(NULL, m->size, PROT_READ, MAP_SHARED, m->fd, 0);
   if (m->data == MAP_FAILED)
     {
        close(m->fd);
        free(m->name);
        free(m);
        return NULL;
     }
   m->ref = 1;
   return m;
}
Exemplo n.º 5
0
static Eina_Bool
_load(Eina_File *ef, const char *key,
      Evas_Image_Property *prop,
      Evas_Image_Load_Opts *opts,
      void *pixels,
      int *error, Eina_Bool get_data)
{
   Eina_Bool res = EINA_FALSE;
   int w = 0, h = 0, alpha = 0;
   const char *dot1 = NULL, *dot2 = NULL, *end, *p;
   char *cmd = NULL, decoders[3][128], buf[4096];
   char *loader = "/evas/utils/evas_image_loader";
   char *img_loader = NULL;
   const char *libdir;
   // eg $libdir/evas/generic_loaders
   int cmd_len, len, decoders_num = 0, try_count = 0;
   int read_data = 0;
   char *tmpfname = NULL, *shmfname = NULL;
   DATA32 *body;
   FILE *f = NULL;

   libdir = _evas_module_libdir_get();
   cmd_len = strlen(libdir);
   cmd_len += strlen(loader);
   img_loader = alloca(cmd_len + 1);
   strcpy(img_loader, libdir);
   strcat(img_loader, loader);

   // params excluding file, key and loadopts
   cmd_len += 1024;
   cmd_len += strlen(eina_file_filename_get(ef)) * 2;
   if (key) cmd_len += strlen(key) * 2;
   cmd = alloca(cmd_len + 1);

   len = strlen(eina_file_filename_get(ef));
   if (len < 1)
     {
        *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
	return EINA_FALSE;
     }
   end = eina_file_filename_get(ef) + len;
   for (p = end - 1; p >= eina_file_filename_get(ef); p--)
     {
        if      ((!dot1) && (*p == '.')) dot1 = p;
        else if ((!dot2) && (*p == '.')) dot2 = p;
        else if ((dot1) && (dot2)) break;
    }
   if (dot2)
     {
        // double extn not too long
        if (((end - dot2) <= 10) && (!illegal_char(dot2)))
          {
             strncpy(&(decoders[decoders_num][0]), img_loader, 127);
             decoders[decoders_num][127] = 0;
             dotcat(&(decoders[decoders_num][0]), dot2);
             decoders_num++;
          }
        // single extn not too long
        if (((end - dot1) <= 5) && (!illegal_char(dot1)))
          {
             strncpy(&(decoders[decoders_num][0]), img_loader, 127);
             decoders[decoders_num][127] = 0;
             dotcat(&(decoders[decoders_num][0]), dot1);
             decoders_num++;
          }
        strncpy(decoders[decoders_num], img_loader, 127);
        decoders[decoders_num][127] = 0;
        decoders_num++;
     }
   else if (dot1)
     {
        // single extn not too long
        if (((end - dot1) <= 5) && (!illegal_char(dot1)))
          {
             strncpy(&(decoders[decoders_num][0]), img_loader, 127);
             decoders[decoders_num][127] = 0;
             dotcat(&(decoders[decoders_num][0]), dot1);
             decoders_num++;
          }
        strncpy(decoders[decoders_num], img_loader, 127);
        decoders[decoders_num][127] = 0;
        decoders_num++;
     }
   else
     {
        strncpy(decoders[decoders_num], img_loader, 127);
        decoders[decoders_num][127] = 0;
        decoders_num++;
     }

   for (try_count = 0; try_count < decoders_num; try_count++)
     {
        // FIXME: strcats could be more efficient, not that it matters much
        // here as we are about to build a cmd to exec via a shell that
        // will interpret shell stuff and path hunt that will then exec the
        // program itself that will dynamically link that will again
        // parse the arguments and finally do something...
        if (access(decoders[try_count], X_OK)) continue;

        strcpy(cmd, decoders[try_count]);
        strcat(cmd, " ");
        // filename first arg
        len = strlen(cmd);
        escape_copy(eina_file_filename_get(ef), cmd + len);
        if (!get_data)
          {
             strcat(cmd, " -head ");
          }
        if (key)
          {
             strcat(cmd, " -key ");
             len = strlen(cmd);
             escape_copy(key, cmd + len);
          }
        if (opts->scale_down_by > 1)
          {
             strcat(cmd, " -opt-scale-down-by ");
             snprintf(buf, sizeof(buf), "%i", opts->scale_down_by);
             strcat(cmd, buf);
          }
        if (opts->dpi > 0.0)
          {
             strcat(cmd, " -opt-dpi ");
             snprintf(buf, sizeof(buf), "%i", (int)(opts->dpi * 1000.0));
             strcat(cmd, buf);
          }
        if ((opts->w > 0) &&
            (opts->h > 0))
          {
             strcat(cmd, " -opt-size ");
             snprintf(buf, sizeof(buf), "%i %i", opts->w, opts->h);
             strcat(cmd, buf);
         }
        f = popen(cmd, "r");
        if (f) break;
     }
   if (!f)
     {
	*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
	return EINA_FALSE;
     }
   while (fgets(buf, sizeof(buf), f))
     {
        len = strlen(buf);
        if (len > 0)
          {
             if (buf[len - 1] == '\n') buf[len - 1] = 0;
             if (!strncmp(buf, "size ", 5))
               {
                  int tw = 0, th = 0;

                  len = sscanf(buf, "%*s %i %i", &tw, &th);
                  if (len == 2)
                    {
                       if ((tw > 0) && (th > 0))
                         {
                            w = tw;
                            h = th;
                         }
                    }
               }
             else if (!strncmp(buf, "alpha ", 6))
               {
                  int ta;

                  len = sscanf(buf, "%*s %i", &ta);
                  if (len == 1)
                    {
                       alpha = ta;
                    }
               }
             else if (!strncmp(buf, "tmpfile ", 8))
               {
                  tmpfname = buf + 8;
                  goto getdata;
               }
#ifdef HAVE_SHM_OPEN
             else if (!strncmp(buf, "shmfile ", 8))
               {
                  shmfname = buf + 8;
                  goto getdata;
               }
#endif
             else if (!strncmp(buf, "data", 4))
               {
                  read_data = 1;
                  goto getdata;
               }
             else if (!strncmp(buf, "done", 4))
               {
                  read_data = 2;
                  goto getdata;
               }
          }
     }
getdata:
   if ((!read_data) && (!tmpfname) && (!shmfname))
     {
	*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
	goto on_error;
     }
   if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
       IMG_TOO_BIG(w, h))
     {
	*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
	goto on_error;
     }

   if (!get_data)
     {
        if (alpha) prop->alpha = 1;
        prop->w = w;
        prop->h = h;
     }
   else
     {
        if ((int)prop->w != w ||
            (int)prop->h != h)
          {
             *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
             goto on_error;
          }
        body = pixels;

        if ((tmpfname) || (shmfname))
          {
             int fd = -1;

             // open
             if (tmpfname)
                fd = open(tmpfname, O_RDONLY, S_IRUSR);
#ifdef HAVE_SHM_OPEN
             else if (shmfname)
                fd = shm_open(shmfname, O_RDONLY, S_IRUSR);
#endif
             if (fd >= 0)
               {
                  void *addr;

                  eina_mmap_safety_enabled_set(EINA_TRUE);

                  // mmap
                  addr = mmap(NULL, w * h * sizeof(DATA32),
                              PROT_READ, MAP_SHARED, fd, 0);
                  if (addr != MAP_FAILED)
                    {
                       memcpy(body, addr, w * h * sizeof(DATA32));
                       munmap(addr, w * h * sizeof(DATA32));
                    }
                  // close
                  if (tmpfname)
                    {
                       close(fd);
                       unlink(tmpfname);
                    }
#ifdef HAVE_SHM_OPEN
                  else if (shmfname)
                    {
                       close(fd);
                       shm_unlink(shmfname);
                    }
#endif
               }
             else
               {
                  *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
                  goto on_error;
               }
          }
        else if (read_data)
          {
             if (fread(body, w * h * sizeof(DATA32), 1, f) != 1)
               {
                  *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
                  goto on_error;
               }
          }
     }

   res = EINA_TRUE;
   *error = EVAS_LOAD_ERROR_NONE;

 on_error:
   if (f) pclose(f);
   return res;
}
Exemplo n.º 6
0
/**
 * @internal
 * @param file The file to parse
 * @return Returns an Eina_Hash with the contents of @a file, or NULL if the
 *         file fails to parse or if the file doesn't exist
 * @brief Parses the ini file @a file into an Eina_Hash
 */
static Eina_Hash *
efreet_ini_parse(const char *file)
{
    Eina_Hash *data = NULL, *section = NULL;
    Eina_Iterator *it = NULL;
    Eina_File_Line *line;
    Eina_File *f;

    EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
    f = eina_file_open(file, EINA_FALSE);
    if (!f)
        return NULL;

    data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free));
    if (!data) goto error;

    /* let's make mmap safe and just get 0 pages for IO erro */
    eina_mmap_safety_enabled_set(EINA_TRUE);

    it = eina_file_map_lines(f);
    if (!it) goto error;
    EINA_ITERATOR_FOREACH(it, line)
    {
        const char *eq;
        unsigned int start = 0;

        /* skip empty lines */
        if (line->length == 0) continue;
        /* skip white space at start of line */
        while ((start < line->length) && (isspace((unsigned char)line->start[start])))
            start++;
        /* skip empty lines */
        if (start == line->length) continue;
        /* skip comments */
        if (line->start[start] == '#') continue;

        /* new section */
        if (line->start[start] == '[')
        {
            const char *head_start;
            const char *head_end;

            head_start = &(line->start[start]) + 1;
            head_end = memchr(line->start, ']', line->length);

            if (head_end)
            {
                char *header;
                size_t len;

                len = head_end - head_start + 1;
                header = alloca(len);

                memcpy(header, head_start, len - 1);
                header[len - 1] = '\0';

                section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del));

                eina_hash_del_by_key(data, header);
                eina_hash_add(data, header, section);
            }
            else
            {
                /* invalid file - skip line? or refuse to parse file? */
                /* just printf for now till we figure out what to do */
//                ERR("Invalid file (%s) (missing ] on group name)", file);
            }
            continue;
        }

        if (!section)
        {
            INF("Invalid file (%s) (missing section)", file);
            goto error;
        }

        eq = memchr(line->start, '=', line->length);

        if (eq)
        {
            const char *key_start, *key_end;
            const char *value_start, *value_end;
            char *key, *value;
            size_t len;

            key_start = &(line->start[start]);
            key_end = eq - 1;

            /* trim whitespace from end of key */
            while ((isspace((unsigned char)*key_end)) && (key_end > key_start))
                key_end--;
            key_end++;

            /* make sure we have a key */
            if (key_start == key_end) continue;

            value_start = eq + 1;
            value_end = line->end;

            /* line->end points to char after '\n' or '\r' */
            value_end--;
            /* trim whitespace from end of value */
            while ((isspace((unsigned char)*value_end)) && (value_end > value_start))
                value_end--;
            value_end++;

            /* trim whitespace from start of value */
            while ((isspace((unsigned char)*value_start)) && (value_start < value_end))
                value_start++;

            len = key_end - key_start + 1;
            key = alloca(len);

            memcpy(key, key_start, len - 1);
            key[len - 1] = '\0';

            /* empty value allowed */
            if (value_end == value_start)
            {
                eina_hash_del_by_key(section, key);
                eina_hash_add(section, key, "");
            }
            else
            {
                len = value_end - value_start + 1;
                value = alloca(len);
                memcpy(value, value_start, len - 1);
                value[len - 1] = '\0';

                eina_hash_del_by_key(section, key);
                eina_hash_add(section, key, efreet_ini_unescape(value));
            }
        }
        else
        {
            /* invalid file... */
            INF("Invalid file (%s) (missing = from key=value pair)", file);
            goto error;
        }
    }
    eina_iterator_free(it);
    eina_file_close(f);

#if 0
    if (!eina_hash_population(data))
    {
        eina_hash_free(data);
        return NULL;
    }
#endif
    return data;
error:
    if (data) eina_hash_free(data);
    if (it) eina_iterator_free(it);

    eina_file_close(f);
    return NULL;
}
Exemplo n.º 7
0
EAPI Eet_Key *
eet_identity_open(const char               *certificate_file,
                  const char               *private_key_file,
                  Eet_Key_Password_Callback cb)
{
#ifdef HAVE_SIGNATURE
   /* Signature declarations */
   Eet_Key *key = NULL;
# ifdef HAVE_GNUTLS
   /* Gnutls private declarations */
   Eina_File *f = NULL;
   void *data = NULL;
   gnutls_datum_t load_file = { NULL, 0 };
   char pass[1024];

   if (!emile_cipher_init()) return NULL;

   /* Init */
   if (!(key = malloc(sizeof(Eet_Key))))
     goto on_error;

   key->references = 1;

   if (gnutls_x509_crt_init(&(key->certificate)))
     goto on_error;

   if (gnutls_x509_privkey_init(&(key->private_key)))
     goto on_error;

   /* Mmap certificate_file */
   f = eina_file_open(certificate_file, 0);
   if (!f)
     goto on_error;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!data) goto on_error;

   /* Import the certificate in Eet_Key structure */
   load_file.data = data;
   load_file.size = eina_file_size_get(f);
   if (gnutls_x509_crt_import(key->certificate, &load_file,
                              GNUTLS_X509_FMT_PEM) < 0)
     goto on_error;

   eina_file_map_free(f, data);

   /* Reset values */
   eina_file_close(f);
   f = NULL;
   data = NULL;
   load_file.data = NULL;
   load_file.size = 0;

   /* Mmap private_key_file */
   f = eina_file_open(private_key_file, 0);
   if (!f)
     goto on_error;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!data)
     goto on_error;

   /* Import the private key in Eet_Key structure */
   load_file.data = data;
   load_file.size = eina_file_size_get(f);
   /* Try to directly import the PEM encoded private key */
   if (gnutls_x509_privkey_import(key->private_key, &load_file,
                                  GNUTLS_X509_FMT_PEM) < 0)
     {
        /* Else ask for the private key pass */
         if (cb && cb(pass, 1024, 0, NULL))
           {
     /* If pass then try to decode the pkcs 8 private key */
               if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
                                                    GNUTLS_X509_FMT_PEM, pass, 0))
                 goto on_error;
           }
         else
         /* Else try to import the pkcs 8 private key without pass */
         if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
                                              GNUTLS_X509_FMT_PEM, NULL, 1))
           goto on_error;
     }

   eina_file_map_free(f, data);
   eina_file_close(f);

   return key;

on_error:
   if (data) eina_file_map_free(f, data);
   if (f) eina_file_close(f);

   if (key)
     {
        if (key->certificate)
          gnutls_x509_crt_deinit(key->certificate);

        if (key->private_key)
          gnutls_x509_privkey_deinit(key->private_key);

        free(key);
     }

# else /* ifdef HAVE_GNUTLS */
   /* Openssl private declarations */
   FILE *fp;
   EVP_PKEY *pkey = NULL;
   X509 *cert = NULL;

   if (!emile_cipher_init()) return NULL;

   /* Load the X509 certificate in memory. */
   fp = fopen(certificate_file, "rb");
   if (!fp)
     return NULL;

   cert = PEM_read_X509(fp, NULL, NULL, NULL);
   fclose(fp);
   if (!cert)
     goto on_error;

   /* Check the presence of the public key. Just in case. */
   pkey = X509_get_pubkey(cert);
   if (!pkey)
     goto on_error;

   /* Load the private key in memory. */
   fp = fopen(private_key_file, "rb");
   if (!fp)
     goto on_error;

   pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
   fclose(fp);
   if (!pkey)
     goto on_error;

   /* Load the certificate and the private key in Eet_Key structure */
   key = malloc(sizeof(Eet_Key));
   if (!key)
     goto on_error;

   key->references = 1;
   key->certificate = cert;
   key->private_key = pkey;

   return key;

on_error:
   if (cert)
     X509_free(cert);

   if (pkey)
     EVP_PKEY_free(pkey);

# endif /* ifdef HAVE_GNUTLS */
#else
   (void) certificate_file;
   (void) private_key_file;
   (void) cb;
#endif /* ifdef HAVE_SIGNATURE */
   return NULL;
}
Exemplo n.º 8
0
Eet_Error
eet_identity_sign(FILE    *fp,
                  Eet_Key *key)
{
#ifdef HAVE_SIGNATURE
   Eet_Error err = EET_ERROR_NONE;
   struct stat st_buf;
   void *data;
   int fd;
   int head[3];
   unsigned char *sign = NULL;
   unsigned char *cert = NULL;
# ifdef HAVE_GNUTLS
   gnutls_datum_t datum = { NULL, 0 };
   size_t sign_len = 0;
   size_t cert_len = 0;
   gnutls_datum_t signum = { NULL, 0 };
   gnutls_privkey_t privkey;
# else /* ifdef HAVE_GNUTLS */
#  if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   EVP_MD_CTX *md_ctx;
#  else
   EVP_MD_CTX md_ctx;
#  endif
   unsigned int sign_len = 0;
   int cert_len = 0;
# endif /* ifdef HAVE_GNUTLS */

   /* A few check and flush pending write. */
   if (!fp || !key || !key->certificate || !key->private_key)
     return EET_ERROR_BAD_OBJECT;

   if (!emile_cipher_init()) return EET_ERROR_NOT_IMPLEMENTED;

   /* Get the file size. */
   fd = fileno(fp);
   if (fd < 0)
     return EET_ERROR_BAD_OBJECT;

   if (fstat(fd, &st_buf) < 0)
     return EET_ERROR_MMAP_FAILED;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   /* Map the file in memory. */
   data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (data == MAP_FAILED)
     return EET_ERROR_MMAP_FAILED;

# ifdef HAVE_GNUTLS
   datum.data = data;
   datum.size = st_buf.st_size;

   /* Get the signature length */
   if (gnutls_privkey_init(&privkey) < 0)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   if (gnutls_privkey_import_x509(privkey, key->private_key, 0) < 0)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   if (gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &datum, &signum) < 0)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   sign = signum.data;
   sign_len = signum.size;

   /* Get the certificate length */
   if (gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
                              &cert_len) &&
       !cert_len)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   /* Get the certificate */
   cert = malloc(cert_len);
   if (!cert ||
       gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
                              &cert_len))
     {
        if (!cert)
          err = EET_ERROR_OUT_OF_MEMORY;
        else
          err = EET_ERROR_SIGNATURE_FAILED;

        goto on_error;
     }

# else /* ifdef HAVE_GNUTLS */
   sign_len = EVP_PKEY_size(key->private_key);
   sign = malloc(sign_len);
   if (!sign)
     {
        err = EET_ERROR_OUT_OF_MEMORY;
        goto on_error;
     }

   /* Do the signature. */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   md_ctx = EVP_MD_CTX_new();
   EVP_SignInit(md_ctx, EVP_sha1());
   EVP_SignUpdate(md_ctx, data, st_buf.st_size);
   err = EVP_SignFinal(md_ctx,
                       sign,
                       (unsigned int *)&sign_len,
                       key->private_key);
   EVP_MD_CTX_free(md_ctx);
#else
   EVP_SignInit(&md_ctx, EVP_sha1());
   EVP_SignUpdate(&md_ctx, data, st_buf.st_size);
   err = EVP_SignFinal(&md_ctx,
                       sign,
                       (unsigned int *)&sign_len,
                       key->private_key);
   EVP_MD_CTX_cleanup(&md_ctx);
#endif
   if (err != 1)
     {
        ERR_print_errors_fp(stdout);
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   /* Give me the der (binary form for X509). */
   cert_len = i2d_X509(key->certificate, &cert);
   if (cert_len < 0)
     {
        ERR_print_errors_fp(stdout);
        err = EET_ERROR_X509_ENCODING_FAILED;
        goto on_error;
     }

# endif /* ifdef HAVE_GNUTLS */
   /* Append the signature at the end of the file. */
   head[0] = (int)htonl ((unsigned int)EET_MAGIC_SIGN);
   head[1] = (int)htonl ((unsigned int)sign_len);
   head[2] = (int)htonl ((unsigned int)cert_len);

   if (fwrite(head, sizeof(head), 1, fp) != 1)
     {
        err = EET_ERROR_WRITE_ERROR;
        goto on_error;
     }

   if (fwrite(sign, sign_len, 1, fp) != 1)
     {
        err = EET_ERROR_WRITE_ERROR;
        goto on_error;
     }

   if (fwrite(cert, cert_len, 1, fp) != 1)
     {
        err = EET_ERROR_WRITE_ERROR;
        goto on_error;
     }

on_error:
# ifdef HAVE_GNUTLS
   if (cert)
     free(cert);

# else /* ifdef HAVE_GNUTLS */
   if (cert)
     OPENSSL_free(cert);

# endif /* ifdef HAVE_GNUTLS */
   if (sign)
     free(sign);

   munmap(data, st_buf.st_size);
   return err;
#else /* ifdef HAVE_SIGNATURE */
   fp = NULL;
   key = NULL;
   return EET_ERROR_NOT_IMPLEMENTED;
#endif /* ifdef HAVE_SIGNATURE */
}