pike.git / src / post_modules / Nettle / nettle.cmod

version» Context lines:

pike.git/src/post_modules/Nettle/nettle.cmod:63:   #ifndef HAVE_STRUCT_YARROW256_CTX_SEED_FILE    static void pike_generate_seed_file(void)    {    struct pike_string *seed_file =    begin_shared_string(YARROW256_SEED_FILE_SIZE);    yarrow256_random(&THIS->ctx, YARROW256_SEED_FILE_SIZE, STR0(seed_file));    if (THIS->seed_file) {    free_string(THIS->seed_file);    }    THIS->seed_file = end_shared_string(seed_file); +  THIS->seed_file->flags |= STRING_CLEAR_ON_EXIT;    }   #else   #define pike_generate_seed_file()   #endif       /*! @decl void create(void|int sources)    *! The number of entropy sources that will feed entropy to the    *! random number generator is given as an argument to Yarrow    *! during instantiation.    *! @seealso
pike.git/src/post_modules/Nettle/nettle.cmod:116:    *! @[min_seed_size], @[get_seed], @[is_seeded]    */    PIKEFUN object seed(string data)    optflags OPT_SIDE_EFFECT;    {    if(data->len < YARROW256_SEED_FILE_SIZE)    Pike_error("Seed must be at least %d characters.\n",    YARROW256_SEED_FILE_SIZE);       NO_WIDE_STRING(data); +  data->flags |= STRING_CLEAR_ON_EXIT;    yarrow256_seed(&THIS->ctx, data->len, STR0(data));    pike_generate_seed_file();    RETURN this_object();    }       /*! @decl int(0..) min_seed_size()    *! Returns the minimal number of characters that the @[seed]    *! needs to properly seed the random number generator.    *! @seealso    *! @[seed]
pike.git/src/post_modules/Nettle/nettle.cmod:144:    *! Returns part of the internal state so that it can    *! be saved for later seeding.    *!    *! @seealso    *! @[seed()], @[random_string()]    */    PIKEFUN string(0..255) get_seed()    optflags OPT_EXTERNAL_DEPEND;    rawtype tDeprecated(tFunc(tNone, tStr8));    { +  struct pike_string * ret;    if( !yarrow256_is_seeded(&THIS->ctx) )    Pike_error("Random generator not seeded.\n");      #ifdef HAVE_STRUCT_YARROW256_CTX_SEED_FILE -  RETURN make_shared_binary_string(THIS->ctx.seed_file, +  ret = make_shared_binary_string(THIS->ctx.seed_file,    YARROW256_SEED_FILE_SIZE); -  +  ret->flags |= STRING_CLEAR_ON_EXIT; +  RETURN ret;   #else    if (THIS->seed_file) {    REF_RETURN THIS->seed_file;    } else { -  +  /* +  * It seems somewhat unreasonable to use uninitialized memory here. +  * Instead, I think the user should be warned. It really isnt a very +  * good source of entropy and may lead to undefined behavior in C. +  * Why not simply return 0 in that case? +  * /arne +  */    struct pike_string *s = begin_shared_string(YARROW256_SEED_FILE_SIZE); -  RETURN end_shared_string(s); +  PIKE_MEM_RW_RANGE(s->str, YARROW256_SEED_FILE_SIZE); +  s = end_shared_string(s); +  s->flags |= STRING_CLEAR_ON_EXIT; +  RETURN s;    }   #endif /* HAVE_STRUCT_YARROW256_CTX_SEED_FILE */    }       /*! @decl int(0..1) is_seeded()    *! Returns 1 if the random generator is seeded and ready    *! to generator output. 0 otherwise.    *! @seealso    *! @[seed]    */
pike.git/src/post_modules/Nettle/nettle.cmod:207:    *!    *! @seealso    *! @[create]    */    PIKEFUN int(0..1) update(string data, int source, int entropy)    optflags OPT_SIDE_EFFECT;    {    int ret;    /* FIXME: Wide strings could actually be supported here */    NO_WIDE_STRING(data); +  data->flags |= STRING_CLEAR_ON_EXIT;    if( !THIS->sources )    Pike_error("This random generator has no sources.\n");    if( source<0 || (unsigned)source>=THIS->ctx.nsources )    Pike_error("Invalid random source.\n");    if( entropy<0 )    Pike_error("Entropy must be positive.\n");    if( entropy>(data->len*8) )    Pike_error("Impossibly large entropy value.\n");    ret = yarrow256_update(&THIS->ctx, source, entropy, data->len,    (const uint8_t *)data->str);
pike.git/src/post_modules/Nettle/nettle.cmod:246:    PIKEFUN string(0..255) random_string(int length)    optflags OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT;    {    struct pike_string *rnd;    if(length < 0)    Pike_error("Invalid length, must be positive.\n");    if( !yarrow256_is_seeded(&THIS->ctx) )    Pike_error("Random generator not seeded.\n");    rnd = begin_shared_string(length);    yarrow256_random(&THIS->ctx, length, (uint8_t *)rnd->str); -  RETURN end_shared_string(rnd); +  rnd = end_shared_string(rnd); +  rnd->flags |= STRING_CLEAR_ON_EXIT; +  RETURN rnd;    }       INIT    {    THIS->sources = NULL;    yarrow256_init(&THIS->ctx, 0, NULL);    }       EXIT    gc_trivial;
pike.git/src/post_modules/Nettle/nettle.cmod:279:    *! void|string magic)    *! Does the crypt_md5 abrakadabra (MD5 + snakeoil).    *! It is assumed that @[salt] does not contain "$".    */   PIKEFUN string(0..127) crypt_md5(string pw, string salt, void|string magic)    optflags OPT_TRY_OPTIMIZE;   {    char *hash;    NO_WIDE_STRING(pw);    NO_WIDE_STRING(salt); +  +  pw->flags |= STRING_CLEAR_ON_EXIT; +     if(!magic)    {    hash = pike_crypt_md5(pw->len, pw->str, salt->len, salt->str,    3, "$1$");    }    else    {    hash = pike_crypt_md5(pw->len, pw->str, salt->len, salt->str,    magic->len, magic->str);    }
pike.git/src/post_modules/Nettle/nettle.cmod:562:    }       /*! @decl string(0..255) crypt(string data)    *! Encrypt/decrypt @[data] and return the result. @[data] must    *! be an integral number of blocks.    */    PIKEFUN string(0..255) crypt(string data) {    unsigned INT8 *result;    INT32 offset = 0;    ONERROR uwp; +  struct pike_string * res;       NO_WIDE_STRING(data);    -  +  data->flags |= STRING_CLEAR_ON_EXIT; +     if(data->len % THIS->block_size)    Pike_error("Data length not multiple of block size.\n");       if(!(result = malloc(data->len)))    SIMPLE_OUT_OF_MEMORY_ERROR("crypt", data->len);    SET_ONERROR (uwp, free, result);       if(THIS->mode == 0) {    while (offset < data->len) {    cbc_encrypt_step((const unsigned INT8 *)data->str + offset,
pike.git/src/post_modules/Nettle/nettle.cmod:588:    }    else {    while (offset < data->len) {    cbc_decrypt_step((const unsigned INT8 *)data->str + offset,    result + offset);    offset += THIS->block_size;    }    }       pop_n_elems(args); -  push_string(make_shared_binary_string((INT8 *)result, offset)); +  res = make_shared_binary_string((INT8 *)result, offset); +  res->flags |= STRING_CLEAR_ON_EXIT; +  push_string(res);    guaranteed_memset(result, 0, offset);       CALL_AND_UNSET_ONERROR (uwp);    }   }      /*! @endclass    */      /*! @class Buffer
pike.git/src/post_modules/Nettle/nettle.cmod:740:    *! Adds data to be encrypted to the buffer. If there's enough    *! data to en/decrypt a block, that will be done, and the result    *! returned. Any uncrypted data will be left in the buffer.    */    PIKEFUN string(0..255) crypt(string data) {    unsigned char *result;    ptrdiff_t roffset = 0;    ptrdiff_t soffset = 0;    ptrdiff_t len;    ONERROR uwp; +  struct pike_string * res;       if (!(result = malloc(data->len + THIS->block_size)))    SIMPLE_OUT_OF_MEMORY_ERROR("crypt", data->len + THIS->block_size);    SET_ONERROR (uwp, free, result);       if (THIS->backlog_len) {    if (data->len >= (THIS->block_size - THIS->backlog_len)) {    MEMCPY(THIS->backlog + THIS->backlog_len, data->str,    (THIS->block_size - THIS->backlog_len));    soffset += (THIS->block_size - THIS->backlog_len);
pike.git/src/post_modules/Nettle/nettle.cmod:804:    }       if (soffset < Pike_sp[-1].u.string->len) {    MEMCPY(THIS->backlog, Pike_sp[-1].u.string->str + soffset,    Pike_sp[-1].u.string->len - soffset);    THIS->backlog_len = Pike_sp[-1].u.string->len - soffset;    }       pop_n_elems(args);    -  push_string(make_shared_binary_string((char *)result, roffset + len)); +  res = make_shared_binary_string((char *)result, roffset + len); +  res->flags |= STRING_CLEAR_ON_EXIT; +  push_string(res);    guaranteed_memset(result, 0, roffset + len);    CALL_AND_UNSET_ONERROR (uwp);    }       /*! @decl string(0..255) pad(void|int method)    *!    *! Pad and encrypt any data left in the buffer.    *!    *! @param method    *! The type of padding to apply to the buffer.
pike.git/src/post_modules/Nettle/nettle.cmod:831:    *! @endint    *! Defaults to Crypto.PAD_SSL for compatibility reasons.    *!    *! @seealso    *! @[unpad()]    */    PIKEFUN string(0..255) pad(void|int method) {    ptrdiff_t i;    int m = 0;    int size = THIS->block_size - THIS->backlog_len; +  struct pike_string * backlog;       if(method)    {    if(TYPEOF(*method) != PIKE_T_INT)    Pike_error("Bad argument type.\n");    m = method->u.integer;    }       switch(m)    {
pike.git/src/post_modules/Nettle/nettle.cmod:878:    THIS->backlog[i] = DO_NOT_WARN((unsigned char)size);    break;    case 4:    /* Null only */    THIS->backlog[i] = 0;    break;    }          THIS->backlog[THIS->block_size - 1] = DO_NOT_WARN((unsigned char)size); +  backlog = make_shared_binary_string((const char *)THIS->backlog, THIS->block_size); +  backlog->flags |= STRING_CLEAR_ON_EXIT; +  push_string(backlog);    -  push_string(make_shared_binary_string((const char *)THIS->backlog, -  THIS->block_size)); -  +     MEMSET(THIS->backlog, 0, THIS->block_size);    THIS->backlog_len = 0;       safe_apply(THIS->object, "crypt", 1);    }       /*! @decl string(0..255) unpad(string data, void|int method)    *!    *! Decrypt and unpad a block of data.    *!
pike.git/src/post_modules/Nettle/nettle.cmod:911:    *! @value Crypto.PAD_ZERO    *! @endint    *! Defaults to Crypto.PAD_SSL for compatibility reasons.    *!    *! @seealso    *! @[pad()]    */    PIKEFUN string(0..255) unpad(string str, void|int method) {    ptrdiff_t len;    int m = 0; +  struct pike_string * ret;       len = str->len;    if( len % THIS->block_size)    Pike_error("String must be integral numbers of blocks.\n");       if( method!=NULL )    {    m = method->u.integer;    pop_stack();    args--;
pike.git/src/post_modules/Nettle/nettle.cmod:965:    len--;    }    }    }       if (len < 0)    Pike_error("String too short to unpad\n");       add_ref(str);    pop_stack(); -  push_string(make_shared_binary_string(str->str, len)); +  ret = make_shared_binary_string(str->str, len); +  ret->flags |= STRING_CLEAR_ON_EXIT; +  push_string(ret);    free_string(str);    }       /*! @decl this_program set_iv(string iv)    *! Set the initialization vector to @[iv].    */    PIKEFUN object set_iv(string iv)    optflags OPT_SIDE_EFFECT;    {    apply(THIS->object, "set_iv", args);