SCM yacl_scm_gen_p256_key_pair (void) { int rc; uint8_t q[YACL_P256_COORD_SIZE*2]; uint8_t d[YACL_P256_COORD_SIZE]; rc = yacl_create_key_pair(q, d); SCM qs = scm_c_make_bytevector (YACL_SHA256_LEN*2); SCM ds = scm_c_make_bytevector (YACL_SHA256_LEN); memcpy (SCM_BYTEVECTOR_CONTENTS (qs), &q, YACL_SHA256_LEN*2); memcpy (SCM_BYTEVECTOR_CONTENTS (ds), &d, YACL_SHA256_LEN); SCM q_list = scm_list_2 (scm_from_locale_symbol ("q"), qs); SCM d_list = scm_list_2 (scm_from_locale_symbol ("d"), ds); SCM curve_list = scm_list_2 (scm_from_locale_symbol ("curve"), scm_from_locale_string("NIST P-256")); SCM l = scm_list_4 (scm_from_locale_symbol ("ecc"), curve_list, q_list, d_list); SCM pri_key = scm_list_2 (scm_from_locale_symbol ("private-key"), l); return pri_key; }
SCM DLL_PUBLIC cl_easy_perform (SCM handle, SCM bvflag, SCM headerflag) { handle_post_t *c_handle; SCM data; CURLcode status; struct scm_flag body_sf, header_sf; SCM_ASSERT (_scm_is_handle (handle), handle, SCM_ARG1, "%curl-easy-perform"); c_handle = _scm_to_handle (handle); body_sf.flag = scm_is_true (bvflag); #if SCM_MAJOR_VERSION == 2 if (body_sf.flag) data = scm_c_make_bytevector (0); else data = scm_c_make_string (0, SCM_MAKE_CHAR('\n')); #else data = scm_c_make_string (0, SCM_MAKE_CHAR('\n')); #endif body_sf.scm = data; header_sf.flag = 0; #if SCM_MAJOR_VERSION == 2 if (header_sf.flag) data = scm_c_make_bytevector (0); else data = scm_c_make_string (0, SCM_MAKE_CHAR('\n')); #else data = scm_c_make_string (0, SCM_MAKE_CHAR('\n')); #endif header_sf.scm = data; if (scm_is_true (headerflag)) { curl_easy_setopt (c_handle->handle, CURLOPT_HEADERFUNCTION, write_callback); curl_easy_setopt (c_handle->handle, CURLOPT_HEADERDATA, &header_sf); curl_easy_setopt (c_handle->handle, CURLOPT_ERRORBUFFER, error_string); } curl_easy_setopt (c_handle->handle, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt (c_handle->handle, CURLOPT_WRITEDATA, &body_sf); curl_easy_setopt (c_handle->handle, CURLOPT_ERRORBUFFER, error_string); /* Do the transfer, and fill c_str with the result */ status = curl_easy_perform (c_handle->handle); if (status != CURLE_OK) { error_code = status; return (SCM_BOOL_F); } if (scm_is_true (headerflag)) return (scm_list_2 (header_sf.scm, body_sf.scm)); return (body_sf.scm); }
/* Change the size of a port's bytevector to NEW_SIZE. This doesn't change `read_buf_size'. */ static void st_resize_port (scm_t_port *pt, scm_t_off new_size) { SCM old_stream = SCM_PACK (pt->stream); const signed char *src = SCM_BYTEVECTOR_CONTENTS (old_stream); SCM new_stream = scm_c_make_bytevector (new_size); signed char *dst = SCM_BYTEVECTOR_CONTENTS (new_stream); unsigned long int old_size = SCM_BYTEVECTOR_LENGTH (old_stream); unsigned long int min_size = min (old_size, new_size); scm_t_off offset = pt->write_pos - pt->write_buf; pt->write_buf_size = new_size; memcpy (dst, src, min_size); scm_remember_upto_here_1 (old_stream); /* reset buffer. */ { pt->stream = SCM_UNPACK (new_stream); pt->read_buf = pt->write_buf = (unsigned char *)dst; pt->read_pos = pt->write_pos = pt->write_buf + offset; pt->write_end = pt->write_buf + pt->write_buf_size; pt->read_end = pt->read_buf + pt->read_buf_size; } }
SCM scm_gunzip_buf(SCM scm_buf, SCM scm_outlen){ //this should typecheck buf for us size_t buflen = scm_c_bytevector_length(scm_buf); uint8_t *buf = (uint8_t*)SCM_BYTEVECTOR_CONTENTS(scm_buf); size_t outlen = scm_to_size_t(scm_outlen); uint8_t *out = scm_gc_malloc_pointerless(outlen, SCM_GC_BYTEVECTOR); z_stream stream = {.next_in = buf, .avail_in = buflen, .next_out = out, .avail_out = outlen, .zalloc = NULL, .zfree = NULL, .opaque = NULL}; //15 | 16 means use 15 bits for the decompression window, and only accept //gzip compressed buffers inflateInit2(&stream, 15 | 16); int status = inflate(&stream, Z_FINISH); if(status != Z_STREAM_END){ //the output buffer was too small //Do something useful here, for now this just makes sure that //we don't cause any errors fprintf(stderr, "Return value was %d, expecting %d\n", status, Z_FINISH); scm_gc_free(out, outlen, SCM_GC_BYTEVECTOR); SCM ret = scm_from_utf8_string(stream.msg); inflateEnd(&stream); return ret; } //I don't know what the tag bits for a bytevector are so I need to //make an empty one. SCM bv = scm_c_make_bytevector(0); SCM_SET_CELL_WORD_1(bv, stream.total_out); SCM_SET_CELL_WORD_2(bv, out); inflateEnd(&stream); return bv; }
SCM yacl_scm_b64url_decode (SCM scmb64) { if (!scm_is_string (scmb64)) scm_throw (scm_from_locale_symbol ("BADSTR"), SCM_BOOL_T); size_t scmb64len, outlen; char * b64url = scm_to_utf8_stringn (scmb64, &scmb64len); if (NULL == b64url) scm_throw (scm_from_locale_symbol ("BADDECODE"), SCM_BOOL_T); uint8_t *decode = yacl_b64url_decode (b64url, &outlen); free (b64url); if (NULL == decode) scm_throw (scm_from_locale_symbol ("BADDECODED"), SCM_BOOL_T); SCM b64 = scm_c_make_bytevector (outlen); memcpy (SCM_BYTEVECTOR_CONTENTS (b64), decode, outlen); free (decode); return b64; }
/* This callback function catches the data passed by libcurl and sends it back as a scheme string */ static size_t write_callback (void *ptr, size_t size, size_t nmemb, void *userdata) { size_t length1, length2; SCM data1, data2; struct scm_flag *sf; sf = (struct scm_flag *) userdata; data1 = sf->scm; #if SCM_MAJOR_VERSION == 2 if (sf->flag) length1 = scm_c_bytevector_length (data1); else length1 = scm_c_string_length (data1); #else length1 = scm_c_string_length (data1); #endif length2 = size * nmemb; /* printf ("In write_callback\n"); */ #if SCM_MAJOR_VERSION == 2 if (sf->flag) { data2 = scm_c_make_bytevector (length1 + length2); memcpy (SCM_BYTEVECTOR_CONTENTS (data2), SCM_BYTEVECTOR_CONTENTS (data1), length1); memcpy (SCM_BYTEVECTOR_CONTENTS (data2) + length1, ptr, length2); } else { data2 = scm_c_make_string (length1 + length2, SCM_MAKE_CHAR('\0')); for (size_t i = 0; i < length1; i ++) { scm_c_string_set_x (data2, i, scm_c_string_ref (data1, i)); } for (size_t i = 0; i < length2; i ++) { scm_c_string_set_x (data2, i + length1, SCM_MAKE_CHAR (((char *)ptr)[i])); } } #else data2 = scm_c_make_string (length1 + length2, SCM_MAKE_CHAR('\0')); memcpy (SCM_STRING_CHARS (data2), SCM_STRING_CHARS (data1), length1); memcpy (SCM_STRING_CHARS (data2) + length1, ptr, length2); #endif sf->scm = data2; return length2; }
SCM yacl_scm_hkdf_sha256 (SCM ikm, SCM salt, SCM info) { int rc; uint8_t * ikm_ptr, *salt_ptr, *info_ptr; size_t ikm_len, salt_len, info_len; if (!scm_is_bytevector (ikm)) scm_throw (scm_from_locale_symbol ("BADIKM"), SCM_BOOL_T); ikm_ptr = SCM_BYTEVECTOR_CONTENTS (ikm); ikm_len = SCM_BYTEVECTOR_LENGTH (ikm); if (SCM_UNBNDP (salt)) { salt_ptr = NULL; salt_len = 0; } else if (!scm_is_bytevector (salt)) scm_throw (scm_from_locale_symbol ("BADSALT"), SCM_BOOL_T); else { salt_ptr = SCM_BYTEVECTOR_CONTENTS(salt); salt_len = SCM_BYTEVECTOR_LENGTH (salt); } if (SCM_UNBNDP (info)) { info_ptr = NULL; info_len = 0; } else if (!scm_is_bytevector (info)) scm_throw (scm_from_locale_symbol ("BADINFO"), SCM_BOOL_T); else { info_ptr = SCM_BYTEVECTOR_CONTENTS(info); info_len = SCM_BYTEVECTOR_LENGTH (info); } SCM out = scm_c_make_bytevector (YACL_SHA256_LEN); rc = yacl_hkdf_256(salt_ptr, salt_len, ikm_ptr, ikm_len, info_ptr, info_len, SCM_BYTEVECTOR_CONTENTS (out), YACL_SHA256_LEN); if (rc) scm_throw (scm_from_locale_symbol ("BADHKDF"), SCM_BOOL_T); return out; }
void test_free_handle_bytevector_postfields(void) { extern SCM cl_CURLOPT_POSTFIELDS; SCM handle = cl_easy_init(); SCM bv = scm_c_make_bytevector (26); for (int i = 0; i <= 25; i ++) SCM_BYTEVECTOR_CONTENTS(bv)[i] = i + 'a'; SCM ret = cl_easy_setopt(handle, scm_variable_ref(cl_CURLOPT_POSTFIELDS), bv, SCM_BOOL_F); gc_free_handle(handle); }
static SCM guile_sock_send_buffer (SCM sock) { svz_socket_t *xsock; int i; SCM bv; scm_assert_smob_type (guile_svz_socket_tag, sock); xsock = (svz_socket_t *) SCM_SMOB_DATA (sock); bv = scm_c_make_bytevector (xsock->send_buffer_fill); for (i = 0; i < xsock->send_buffer_fill; i ++) scm_c_bytevector_set_x (bv, i, (xsock->send_buffer[i])); return bv; }
SCM yacl_scm_sha256 (SCM bv) { int rc; uint8_t out[YACL_SHA256_LEN] = {}; signed char* p = SCM_BYTEVECTOR_CONTENTS (bv); size_t len = SCM_BYTEVECTOR_LENGTH (bv); rc = yacl_sha256 (p, len, out); SCM digest = scm_c_make_bytevector (YACL_SHA256_LEN); memcpy (SCM_BYTEVECTOR_CONTENTS (digest), &out, YACL_SHA256_LEN); return digest; }
SCM yacl_scm_p256_sign(SCM data, SCM d) { int rc; uint8_t out[YACL_SHA256_LEN*2] = {}; unsigned char* data_ptr = SCM_BYTEVECTOR_CONTENTS (data); size_t data_len = SCM_BYTEVECTOR_LENGTH (data); unsigned char* d_ptr = SCM_BYTEVECTOR_CONTENTS (d); size_t d_len = SCM_BYTEVECTOR_LENGTH (d); rc = yacl_hash_ecdsa_sign(data_ptr, data_len, d_ptr, out); SCM sig = scm_c_make_bytevector (YACL_SHA256_LEN*2); memcpy (SCM_BYTEVECTOR_CONTENTS (sig), &out, YACL_SHA256_LEN*2); return sig; }
SCM yacl_scm_get_random (SCM len) { if (!scm_is_integer (len)) goto EXCEPTION; size_t rndlen = scm_to_size_t (len); SCM rnd = scm_c_make_bytevector (rndlen); int rc = yacl_get_random(SCM_BYTEVECTOR_CONTENTS (rnd), rndlen); if (rc) goto EXCEPTION; else goto OUT; EXCEPTION: scm_throw (scm_from_locale_symbol ("BADRANDOM"), SCM_BOOL_T); OUT: return rnd; }
/* Return a new string port with MODES. If STR is #f, a new backing buffer is allocated; otherwise STR must be a string and a copy of it serves as the buffer for the new port. */ SCM scm_mkstrport (SCM pos, SCM str, long modes, const char *caller) { SCM z, buf; scm_t_port *pt; const char *encoding; size_t read_buf_size, str_len, c_pos; char *c_buf; if (!((modes & SCM_WRTNG) || (modes & SCM_RDNG))) scm_misc_error ("scm_mkstrport", "port must read or write", SCM_EOL); encoding = scm_i_default_port_encoding (); if (scm_is_false (str)) { /* Allocate a new buffer to write to. */ str_len = INITIAL_BUFFER_SIZE; buf = scm_c_make_bytevector (str_len); c_buf = (char *) SCM_BYTEVECTOR_CONTENTS (buf); /* Reset `read_buf_size'. It will contain the actual number of bytes written to the port. */ read_buf_size = 0; c_pos = 0; } else { /* STR is a string. */ char *copy; SCM_ASSERT (scm_is_string (str), str, SCM_ARG1, caller); /* Create a copy of STR in ENCODING. */ copy = scm_to_stringn (str, &str_len, encoding, SCM_FAILED_CONVERSION_ERROR); buf = scm_c_make_bytevector (str_len); c_buf = (char *) SCM_BYTEVECTOR_CONTENTS (buf); memcpy (c_buf, copy, str_len); free (copy); c_pos = scm_to_unsigned_integer (pos, 0, str_len); read_buf_size = str_len; } z = scm_c_make_port_with_encoding (scm_tc16_strport, modes, encoding, scm_i_default_port_conversion_handler (), (scm_t_bits)buf); pt = SCM_PTAB_ENTRY (z); pt->write_buf = pt->read_buf = (unsigned char *) c_buf; pt->read_pos = pt->write_pos = pt->read_buf + c_pos; pt->read_buf_size = read_buf_size; pt->write_buf_size = str_len; pt->write_end = pt->read_end = pt->read_buf + pt->read_buf_size; pt->rw_random = 1; return z; }