Example #1
0
static SLang_BString_Type *
concat_bstrings (SLang_BString_Type *a, SLang_BString_Type *b)
{
   unsigned int len;
   SLang_BString_Type *c;
   char *bytes;

   len = a->len + b->len;

#if SLANG_USE_TMP_OPTIMIZATION
   if ((a->num_refs == 1)	       /* owned by stack */
       && (a->ptr_type == IS_BSTRING)
       && (len <= a->malloced_len))
     {
	bytes = (char *)a->v.bytes;
	memcpy (bytes + a->len, (char *)BS_GET_POINTER(b), b->len);
	bytes[len] = 0;		       /* ok to \0 terminate --- see above */
	a->len = len;
	a->num_refs++;
	return a;
     }
#endif

   if (NULL == (c = SLbstring_create (NULL, len)))
     return NULL;

   bytes = (char *)BS_GET_POINTER(c);

   memcpy (bytes, (char *)BS_GET_POINTER(a), a->len);
   memcpy (bytes + a->len, (char *)BS_GET_POINTER(b), b->len);
   bytes[len] = 0;

   return c;
}
Example #2
0
static void sl_base64_decode (void){
  char* input, *in;
  BIO* bmem,* b64;
  SLang_BString_Type* output;
  int i, outlen;
  char nl[]="\n";
  
  if (SLang_Num_Function_Args != 1 ||
      SLang_pop_slstring(&in) == -1 ){
    return; }

  /* For some reason, the input is required to have a newline at the
     end, doesn't matter how many, so tack one on here*/
  input = SLang_concat_slstrings(in,nl);
  SLang_free_slstring(in);

  unsigned char* buff = (char*)malloc((int)strlen(input)+1);
  memset(buff,0,(int)strlen(input));

  b64  = BIO_new(BIO_f_base64());
  bmem = BIO_new_mem_buf(input,(int)strlen(input));
  bmem = BIO_push(b64,bmem);
  outlen = BIO_read(bmem,buff,(int)strlen(input));
  BIO_free_all(bmem);

  output = SLbstring_create(buff, outlen);

  SLang_push_bstring(output);
  SLang_free_slstring(input);
  SLbstring_free(output);
  free(buff);
}
Example #3
0
static void sl_ssl_read(void){
  SLssl_Type *ssl;
  SLang_MMT_Type *sslmmt;
  SLang_Ref_Type *buff;
  void *ibuff;
  SLang_BString_Type *data;
  int r, rlen;
  
  if (SLang_pop_integer(&rlen)==-1 ||
      SLang_pop_ref(&buff)==-1 ||
      NULL==(sslmmt=SLang_pop_mmt(SLssl_Type_Id)))
    return;

  ssl=(SLssl_Type *)SLang_object_from_mmt(sslmmt);

  ibuff=(void *)malloc(rlen);

  r=SSL_read((SSL *)ssl->ssl,ibuff,rlen);

  data=SLbstring_create((unsigned char *)ibuff,r);

  SLang_assign_to_ref(buff, SLANG_BSTRING_TYPE, (VOID_STAR)&data);

  if (r>=0)
    SLang_push_integer(r);
  else
    SLang_verror(r,"SSL read returned error code %d",
		 SSL_get_error((SSL *)ssl->ssl,r));

  SLang_free_ref(buff);
}
Example #4
0
static void sl_decrypt (void){
  /* input types */
  char *ctype;
  unsigned char *outbuf, *iiv, *ikey, *idata;
  SLang_BString_Type *iv, *key, *data;
  /* internal types */
  EVP_CIPHER_CTX ctx;
  const EVP_CIPHER *cipher;
  int outlen, tmplen, dlen, i;
  /* output types */
  SLang_BString_Type *output;

  if (SLang_Num_Function_Args != 4 ||
      SLang_pop_slstring(&ctype) == -1 ){
    return; }

  cipher = EVP_get_cipherbyname(ctype);
  if (!cipher){
    SLang_verror(SL_UNDEFINED_NAME,"could not find cipher %s",ctype);
    return;
  }
  
  if (SLang_pop_bstring(&iv) == -1 ||
      SLang_pop_bstring(&key) == -1 ||
      SLang_pop_bstring(&data) == -1 ){
    return; }

  iiv = SLbstring_get_pointer (iv,&i);
  ikey = SLbstring_get_pointer (key,&i);
  idata = SLbstring_get_pointer (data,&dlen);

  outbuf = (char*)malloc(dlen+EVP_CIPHER_block_size(cipher));

  EVP_CIPHER_CTX_init(&ctx);
  EVP_DecryptInit_ex(&ctx, cipher, NULL, ikey, iiv);
  
  if (!EVP_DecryptUpdate(&ctx, outbuf, &outlen, idata, dlen)){
    return; /*emit an error here*/
  }
  if (!EVP_DecryptFinal(&ctx, outbuf + outlen, &tmplen)){
    return; /*emit an error here*/
  }
  outlen+=tmplen;

  output = SLbstring_create (outbuf, outlen);
  
  SLang_push_bstring(output);
  SLbstring_free(output);
  SLbstring_free(data);
  SLbstring_free(key);
  SLbstring_free(iv);
  free(outbuf);
}
Example #5
0
static SLang_BString_Type *
concat_bstrings (SLang_BString_Type *a, SLang_BString_Type *b)
{
   unsigned int len;
   SLang_BString_Type *c;
   char *bytes;

   len = a->len + b->len;

   if (NULL == (c = SLbstring_create (NULL, len)))
     return NULL;

   bytes = (char *)BS_GET_POINTER(c);

   memcpy (bytes, (char *)BS_GET_POINTER(a), a->len);
   memcpy (bytes + a->len, (char *)BS_GET_POINTER(b), b->len);

   return c;
}
Example #6
0
static void _iconv_reset_shift(ICONV_Type *it)
{
   size_t n = SHIFT_BUF_LEN;
   char buf[SHIFT_BUF_LEN], *p = buf;
   SLang_BString_Type *bstr;
   size_t rc;

   rc = iconv(it->cd, NULL, NULL, &p, &n);
   if ((rc == (size_t)(-1)) || (n > rc))
     {
	SLang_verror (SL_Internal_Error, "Internal error: shift buffer too small in iconv_reset_shift!");
	return;
     }
   buf[SHIFT_BUF_LEN-n] = '\0';
   bstr = SLbstring_create((unsigned char *)buf, SHIFT_BUF_LEN-n);
   if (bstr == NULL)
     return;

   (void) SLang_push_bstring(bstr);
   SLbstring_free (bstr);
}
Example #7
0
static void sl_ssl_get_cert(void){
  SLssl_Type *ssl;
  SLang_MMT_Type *sslmmt;
  STACK_OF(X509) *cert;
  unsigned char **buf;
  SLang_BString_Type **certout;
  SLang_Array_Type *arr;
  SLindex_Type nelem;
  int len,i;

  if (NULL==(sslmmt=SLang_pop_mmt(SLssl_Type_Id)))
    return;

  ssl=(SLssl_Type *)SLang_object_from_mmt(sslmmt);

  cert=SSL_get_peer_cert_chain((SSL *)ssl->ssl);

  if (cert==NULL)
    return NULL;

  nelem=(SLindex_Type)sk_X509_num(cert);
  // now we have chain of certs, create array of pointers and the
  // array to hold them
  buf = (unsigned char **)malloc(nelem*sizeof(unsigned char *));
  arr = SLang_create_array(SLANG_BSTRING_TYPE,0,NULL,&nelem,1);
  // array data structure is of bstring type
  certout = (SLang_BString_Type **)arr->data;
  
  for (i=0;i<nelem;i++){
    buf[i] = NULL;
    len = i2d_X509(sk_X509_value(cert,i), &(buf[i]));
    certout[i] = SLbstring_create(buf[i],len);
  }
  
  SLang_push_array(arr,1);
  // free the X509 stack
  sk_X509_pop_free(cert,X509_free);
}
Example #8
0
static void sl_hmac (void){
  char *dtype;
  SLang_BString_Type *key, *data;
  unsigned char *ikey, *idata;
  unsigned char hash[EVP_MAX_MD_SIZE];
  unsigned int hashlen, klen, dlen;
  SLang_BString_Type *output;
  const EVP_MD *md;

  if (SLang_Num_Function_Args != 3 ||
      SLang_pop_slstring(&dtype) == -1 ){
    return; } /* should return error there of course */

  md=EVP_get_digestbyname(dtype);
  if (!md){
    SLang_verror(SL_UNDEFINED_NAME,"could not find digest %s",dtype);
    SLang_free_slstring(dtype);
    return; }

  if (SLang_pop_bstring(&key) == -1 ||
      SLang_pop_bstring(&data) == -1 ){
    return; }

  ikey = SLbstring_get_pointer(key, &klen);
  idata = SLbstring_get_pointer(data, &dlen);
  
  HMAC(md,ikey,klen,idata,dlen,&hash,&hashlen);

  output = SLbstring_create(hash, hashlen);

  SLang_push_bstring(output);
  SLbstring_free(data);
  SLbstring_free(key);
  SLbstring_free(output);
  SLang_free_slstring(dtype);
}
Example #9
0
static void sl_digest (void){
  SLang_BString_Type* data; /* we will give a slang string */
  unsigned char output[EVP_MAX_MD_SIZE];
  const EVP_MD *md;
  EVP_MD_CTX ctx;
  char* dtype;
  int dlen, hashlen;
  SLang_BString_Type *out;
  
  if (SLang_Num_Function_Args != 2 ||
      SLang_pop_slstring(&dtype) == -1 ){
    return;}

  md = EVP_get_digestbyname(dtype);
  if (!md){
    SLang_verror(SL_UNDEFINED_NAME,"could not find digest %s",dtype);
    SLang_free_slstring(dtype);
    return;
  }
  
  if (SLang_pop_bstring(&data) == -1 ){
    return;
  }

  unsigned char* idata = SLbstring_get_pointer (data,&dlen);

  EVP_MD_CTX_init(&ctx);
  EVP_DigestInit_ex(&ctx, md, NULL);
  EVP_DigestUpdate(&ctx, idata, dlen);
  EVP_DigestFinal(&ctx, output, &hashlen);

  out = SLbstring_create (output, hashlen);
  SLang_push_bstring(out);
  SLbstring_free(data);
  SLbstring_free(out);
}
Example #10
0
static void _iconv(ICONV_Type *it, SLang_BString_Type *bstr)
{
   char *buf = NULL;
   size_t rc;
   char ICONV_CONST *instr;
   char *outstr;
   size_t inn, outn, bufn;
   size_t fail = (size_t)-1;
   SLstrlen_Type bstrlen;

   if (NULL == (instr = (char ICONV_CONST *)SLbstring_get_pointer(bstr, &bstrlen)))
     return;
   inn = (size_t) bstrlen;

   bufn = outn = 2*inn + 2;
   if (NULL == (buf = (char *)SLmalloc(bufn)))
     return;

   outstr = buf;

   while (1)
     {
	errno = 0;
	rc = iconv(it->cd, &instr, &inn, &outstr, &outn);
	if (rc != (size_t)-1)
	  break; /* ok! */

	if (fail == inn)
	  {
	     SLang_verror (SL_Unknown_Error, "Unknown error in iconv");
	     goto error;
	  }

	fail = inn;
	switch (errno)
	  {
	   case EILSEQ:
	     SLang_verror (SL_InvalidUTF8_Error, "Invalid multibyte sequence or unable to convert to the target encoding");
	     goto error;
	   case EINVAL:
	     SLang_verror (SL_InvalidUTF8_Error, "Incomplete multibyte sequence");
	     goto error;
	   case 0:
	     /* drop */
	     /* grrrr
	      * At least on windows, libiconv returns with errno = 0
	      * (or unmodified?) when there's no more roon on outstr
	      * if so, fallback
	      */
	   case E2BIG:
	       {
		  char *p;
		  long outdelta;

		  outdelta = outstr - buf;
		  outn += bufn;
		  bufn += bufn;
		  p = (char *)SLrealloc(buf, bufn);
		  if (p == NULL)
		    goto error;
		  buf = p;
		  outstr = buf + outdelta;
	       }
	     break;
	   default:
	     SLang_verror (SL_Unknown_Error, "Unknown iconv error");
	     goto error;
	  }
     }

   bstr = SLbstring_create((unsigned char *) buf, outstr - buf);
   if (bstr != NULL)
     (void) SLang_push_bstring(bstr);
   SLbstring_free (bstr);
   /* drop */
error:
   SLfree(buf);
}
Example #11
0
static void sl_generate_key (void){
  char* pass, *ctype, *dtype;
  SLang_BString_Type* salta;
  const EVP_CIPHER *cipher;
  const EVP_MD *md;
  unsigned char *salt;
  unsigned char *key;
  unsigned char *iv;
  SLang_BString_Type* outkey, *outiv;
  int count,i,keylen,ivlen,saltlen;

  if (SLang_Num_Function_Args != 5 ||
      SLang_pop_slstring(&dtype) == -1 ||
      SLang_pop_slstring(&ctype) == -1 ){
    return; }
  
  cipher = EVP_get_cipherbyname(ctype);
  if (!cipher){
    SLang_verror(SL_UNDEFINED_NAME,"could not find cipher %s",ctype);
    SLang_free_slstring(ctype);
    return;
  }
  md = EVP_get_digestbyname(dtype);
  if (!md){
    SLang_verror(SL_UNDEFINED_NAME,"could not find digest %s",dtype);
    SLang_free_slstring(ctype);
    SLang_free_slstring(dtype);
    return;
  }

  if (SLang_pop_integer(&count) == -1 ||
      SLang_pop_bstring(&salta) == -1 ||
      SLang_pop_slstring(&pass) == -1 ){
    return; }

  keylen = EVP_CIPHER_key_length(cipher);
  ivlen  = EVP_CIPHER_iv_length(cipher);
  key = (char*)malloc(keylen);
  iv  = (char*)malloc(ivlen);

  salt = SLbstring_get_pointer(salta,&saltlen);
  
  if (saltlen==0){
    salt=NULL;
  }
  else if (saltlen!=8){
    SLang_verror(SL_USAGE_ERROR,"Salt must not exceed 8 bytes");
    SLbstring_free(salta);
    SLang_free_slstring(pass);
    SLang_free_slstring(ctype);
    SLang_free_slstring(dtype);
    return;
  }
    
  
  EVP_BytesToKey(cipher,md,salt,pass,(int)strlen(pass),count,key,iv);

  outkey = SLbstring_create(key, keylen);
  outiv  = SLbstring_create(iv, ivlen);

  SLang_push_bstring(outkey);
  SLang_push_bstring(outiv);
  SLbstring_free(salta);
  SLbstring_free(outkey);
  SLbstring_free(outiv);
  SLang_free_slstring(pass);
  SLang_free_slstring(ctype);
  SLang_free_slstring(dtype);
  free(key);free(iv);
}