static mrb_value mrb_ecdsa_sign(mrb_state *mrb, mrb_value self) { ctr_drbg_context *ctr_drbg; unsigned char buf[512], str[1024]; int i, j, len=0, ret=0; ecdsa_context *ecdsa; mrb_value hash, obj; memset(buf, 0, sizeof( buf ) ); mrb_get_args(mrb, "S", &hash); obj = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@ctr_drbg")); ecdsa = DATA_CHECK_GET_PTR(mrb, self, &mrb_ecdsa_type, ecdsa_context); ctr_drbg = DATA_CHECK_GET_PTR(mrb, obj, &mrb_ctr_drbg_type, ctr_drbg_context); ret = ecdsa_write_signature(ecdsa, RSTRING_PTR(hash), RSTRING_LEN(hash), buf, &len, ctr_drbg_random, ctr_drbg); for(i=0, j=0; i < len; i++,j+=2) { sprintf(&str[j], "%c%c", "0123456789ABCDEF" [buf[i] / 16], "0123456789ABCDEF" [buf[i] % 16] ); } if (ret == 0) { return mrb_str_new(mrb, &str, len*2); } else { return mrb_fixnum_value(ret); } }
static mrb_value mrb_ssl_set_rng(mrb_state *mrb, mrb_value self) { ssl_context *ssl; ctr_drbg_context *ctr_drbg; mrb_value rng; mrb_get_args(mrb, "o", &rng); mrb_data_check_type(mrb, rng, &mrb_ctr_drbg_type); ctr_drbg = DATA_CHECK_GET_PTR(mrb, rng, &mrb_ctr_drbg_type, ctr_drbg_context); ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ssl_set_rng(ssl, ctr_drbg_random, ctr_drbg); return mrb_true_value(); }
static mrb_value mrb_ecdsa_private_key(mrb_state *mrb, mrb_value self) { unsigned char buf[300]; unsigned char str[600]; ecdsa_context *ecdsa; mrb_value public_key; size_t len, i, j; ecdsa = DATA_CHECK_GET_PTR(mrb, self, &mrb_ecdsa_type, ecdsa_context); memset(&str, 0, sizeof(str)); memset(&buf, 0, sizeof(buf)); if( ecp_point_write_binary( &ecdsa->grp, &ecdsa->d, POLARSSL_ECP_PF_COMPRESSED, &len, buf, sizeof(buf) ) != 0 ) { mrb_raise(mrb, E_RUNTIME_ERROR, "can't extract Public Key"); return mrb_false_value(); } for(i=0, j=0; i < len; i++,j+=2) { sprintf(&str[j], "%c%c", "0123456789ABCDEF" [buf[i] / 16], "0123456789ABCDEF" [buf[i] % 16] ); } /*return mrb_str_new(mrb, str, len*2);*/ return mrb_str_new(mrb, &str[2], len*2 - 2); }
static mrb_value mrb_ssl_close(mrb_state *mrb, mrb_value self) { ssl_context *ssl; ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); memset(ssl, 0, sizeof(ssl_context)); return mrb_true_value(); }
static mrb_value mrb_ssl_fileno(mrb_state *mrb, mrb_value self) { ssl_context *ssl; mrb_int fd=0; ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); fd = *((int *)ssl->p_recv); return mrb_fixnum_value(fd); }
static mrb_value mrb_ssl_bytes_available(mrb_state *mrb, mrb_value self) { ssl_context *ssl; mrb_int count=0; ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ioctl(*((int *)ssl->p_recv), FIONREAD, &count); return mrb_fixnum_value(count); }
static mrb_value mrb_ssl_set_authmode(mrb_state *mrb, mrb_value self) { ssl_context *ssl; mrb_int authmode; mrb_get_args(mrb, "i", &authmode); ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ssl_set_authmode(ssl, authmode); return mrb_true_value(); }
static mrb_value mrb_ssl_close_notify(mrb_state *mrb, mrb_value self) { ssl_context *ssl; int ret; ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ret = ssl_close_notify(ssl); if (ret < 0) { mrb_raise(mrb, E_SSL_ERROR, "ssl_close_notify() returned E_SSL_ERROR"); } return mrb_true_value(); }
static mrb_value mrb_ssl_set_socket(mrb_state *mrb, mrb_value self) { ssl_context *ssl; struct mrb_io *fptr; mrb_value socket; mrb_get_args(mrb, "o", &socket); mrb_data_check_type(mrb, socket, &mrb_io_type); fptr = DATA_CHECK_GET_PTR(mrb, socket, &mrb_io_type, struct mrb_io); ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ssl_set_bio( ssl, net_recv, &fptr->fd, net_send, &fptr->fd ); return mrb_true_value(); }
static mrb_value mrb_ecdsa_generate_key(mrb_state *mrb, mrb_value self) { ctr_drbg_context *ctr_drbg; ecdsa_context *ecdsa; mrb_int curve=0; mrb_value obj, curve_obj; int ret; ecdsa = DATA_CHECK_GET_PTR(mrb, self, &mrb_ecdsa_type, ecdsa_context); obj = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@ctr_drbg")); curve_obj = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@curve")); ctr_drbg = DATA_CHECK_GET_PTR(mrb, obj, &mrb_ctr_drbg_type, ctr_drbg_context); if (mrb_fixnum_p(curve_obj)) { curve = mrb_fixnum(curve_obj); } else { return mrb_false_value(); } if(ecdsa_genkey(ecdsa, curve, ctr_drbg_random, ctr_drbg) == 0) { return mrb_true_value(); } else { return mrb_false_value(); } }
static mrb_value mrb_ssl_write(mrb_state *mrb, mrb_value self) { ssl_context *ssl; mrb_value msg; char *buffer; int ret; mrb_get_args(mrb, "S", &msg); ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); buffer = RSTRING_PTR(msg); ret = ssl_write(ssl, (const unsigned char *)buffer, RSTRING_LEN(msg)); if (ret < 0) { mrb_raise(mrb, E_SSL_ERROR, "ssl_write() returned E_SSL_ERROR"); } return mrb_true_value(); }
static mrb_value mrb_ssl_handshake(mrb_state *mrb, mrb_value self) { ssl_context *ssl; int ret; ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ret = ssl_handshake(ssl); if (ret < 0) { if (ret == POLARSSL_ERR_NET_WANT_READ) { mrb_raise(mrb, E_NETWANTREAD, "ssl_handshake() returned POLARSSL_ERR_NET_WANT_READ"); } else if (ret == POLARSSL_ERR_NET_WANT_WRITE) { mrb_raise(mrb, E_NETWANTWRITE, "ssl_handshake() returned POLARSSL_ERR_NET_WANT_WRITE"); } else { mrb_raise(mrb, E_SSL_ERROR, "ssl_handshake() returned E_SSL_ERROR"); } } return mrb_true_value(); }
static mrb_value mrb_ssl_read(mrb_state *mrb, mrb_value self) { ssl_context *ssl; mrb_int maxlen = 0; mrb_value buf; int ret; mrb_get_args(mrb, "i", &maxlen); buf = mrb_str_buf_new(mrb, maxlen); ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ret = ssl_read(ssl, (unsigned char *)RSTRING_PTR(buf), maxlen); if ( ret == 0 || ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) { return mrb_nil_value(); } else if (ret < 0) { mrb_raise(mrb, E_SSL_ERROR, "ssl_read() returned E_SSL_ERROR"); } else { mrb_str_resize(mrb, buf, ret); } return buf; }
static mrb_value mrb_ecdsa_load_pem(mrb_state *mrb, mrb_value self) { ecdsa_context *ecdsa; pk_context pkey; mrb_value pem; int ret = 0; mrb_get_args(mrb, "S", &pem); pk_init( &pkey ); ret = pk_parse_key(&pkey, RSTRING_PTR(pem), RSTRING_LEN(pem), NULL, 0); if (ret == 0) { ecdsa = DATA_CHECK_GET_PTR(mrb, self, &mrb_ecdsa_type, ecdsa_context); ret = ecdsa_from_keypair(ecdsa, pk_ec(pkey)); if (ret == 0) { return mrb_true_value(); } } pk_free( &pkey ); mrb_raise(mrb, E_RUNTIME_ERROR, "can't parse pem"); return mrb_false_value(); }
static mrb_value mrb_ctrdrbg_initialize(mrb_state *mrb, mrb_value self) { ctr_drbg_context *ctr_drbg; entropy_context *entropy_p; mrb_value entp, pers; int ret; ctr_drbg = (ctr_drbg_context *)DATA_PTR(self); if (ctr_drbg) { mrb_free(mrb, ctr_drbg); } DATA_TYPE(self) = &mrb_ctr_drbg_type; DATA_PTR(self) = NULL; mrb_get_args(mrb, "o|S", &entp, &pers); if (mrb_type(entp) != MRB_TT_DATA) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } entropy_p = DATA_CHECK_GET_PTR(mrb, entp, &mrb_entropy_type, entropy_context); ctr_drbg = (ctr_drbg_context *)mrb_malloc(mrb, sizeof(ctr_drbg_context)); DATA_PTR(self) = ctr_drbg; if (mrb_string_p(pers)) { mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@pers"), pers); ret = ctr_drbg_init(ctr_drbg, entropy_func, entropy_p, RSTRING_PTR(pers), RSTRING_LEN(pers)); } else { ret = ctr_drbg_init(ctr_drbg, entropy_func, entropy_p, NULL, 0 ); } if (ret == POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ) { mrb_raise(mrb, E_RUNTIME_ERROR, "Could not initialize entropy source"); } return self; }
static mrb_value mrb_ssl_read(mrb_state *mrb, mrb_value self) { ssl_context *ssl; mrb_int maxlen = 0; mrb_value value; char *buf; int ret; mrb_get_args(mrb, "i", &maxlen); buf = malloc(maxlen); ssl = DATA_CHECK_GET_PTR(mrb, self, &mrb_ssl_type, ssl_context); ret = ssl_read(ssl, buf, maxlen); if ( ret == 0 || ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY || buf == NULL) { value = mrb_nil_value(); } else if (ret < 0) { mrb_raise(mrb, E_SSL_ERROR, "ssl_read() returned E_SSL_ERROR"); value = mrb_nil_value(); } else { value = mrb_str_new(mrb, buf, ret); } if(buf != NULL) free(buf); return value; }