Exemplo n.º 1
0
// drop all pending requests for the given UID from the global list
static void network_drop_pending_requests(uint32_t uid) {
	Node *pending_request_global_node = _pending_request_sentinel.next;
	Node *pending_request_global_node_next;
	PendingRequest *pending_request;
	char base58[BASE58_MAX_LENGTH];
	int count = 0;

	while (pending_request_global_node != &_pending_request_sentinel) {
		pending_request = containerof(pending_request_global_node,
		                              PendingRequest, global_node);
		pending_request_global_node_next = pending_request_global_node->next;

		if (pending_request->header.uid == uid) {
			pending_request_remove_and_free(pending_request);

			++count;
		}

		pending_request_global_node = pending_request_global_node_next;
	}

	if (count > 0) {
		log_warn("Dropped %d pending request(s) (uid: %s)",
		         count, base58_encode(base58, uint32_from_le(uid)));
	}
}
Exemplo n.º 2
0
void client_send_red_brick_enumerate(Client *client, EnumerationType type) {
    EnumerateCallback enumerate_callback;
    uint32_t uid = red_usb_gadget_get_uid(); // always little endian

    memset(&enumerate_callback, 0, sizeof(enumerate_callback));

    enumerate_callback.header.uid = uid;
    enumerate_callback.header.length = sizeof(enumerate_callback);
    enumerate_callback.header.function_id = CALLBACK_ENUMERATE;
    packet_header_set_sequence_number(&enumerate_callback.header, 0);
    packet_header_set_response_expected(&enumerate_callback.header, true);

    base58_encode(enumerate_callback.uid, uint32_from_le(uid));
    enumerate_callback.connected_uid[0] = '0';
    enumerate_callback.position = '0';
    enumerate_callback.hardware_version[0] = 1; // FIXME
    enumerate_callback.hardware_version[1] = 0;
    enumerate_callback.hardware_version[2] = 0;
    enumerate_callback.firmware_version[0] = _redapid_version[0];
    enumerate_callback.firmware_version[1] = _redapid_version[1];
    enumerate_callback.firmware_version[2] = _redapid_version[2];
    enumerate_callback.device_identifier = uint16_to_le(RED_BRICK_DEVICE_IDENTIFIER);
    enumerate_callback.enumeration_type = type;

    client_dispatch_response(client, NULL, (Packet *)&enumerate_callback, true, false);
}
Exemplo n.º 3
0
static void red_stack_spi_insert_position(REDStackSlave *slave) {
	if (_red_stack.packet_from_spi.header.function_id == CALLBACK_ENUMERATE ||
	    _red_stack.packet_from_spi.header.function_id == FUNCTION_GET_IDENTITY) {
		EnumerateCallback *enum_cb = (EnumerateCallback *)&_red_stack.packet_from_spi;

		if (enum_cb->position == '0') {
			enum_cb->position = '0' + slave->stack_address + 1;
			base58_encode(enum_cb->connected_uid, uint32_from_le(red_usb_gadget_get_uid()));
		}
	}
}
Exemplo n.º 4
0
/*
 * Base58check encode.
 */
static bool base58check_encode(char *str, size_t slen, const uint8_t *data,
    size_t dlen)
{
    uint8_t res[32];
    PN_sha256d(data, dlen, res);
    uint8_t tmp[dlen + 4];
    memcpy(tmp, data, dlen);
    tmp[dlen+0] = res[0];
    tmp[dlen+1] = res[1];
    tmp[dlen+2] = res[2];
    tmp[dlen+3] = res[3];
    return base58_encode(str, slen, tmp, sizeof(tmp));
}
Exemplo n.º 5
0
cstring *base58_encode_check(unsigned char addrtype, bool have_addrtype,
			     const void *data, size_t data_len)
{
	cstring *s = cstr_new_sz(data_len + 1 + 4);

	if (have_addrtype)
		cstr_append_c(s, addrtype);
	cstr_append_buf(s, data, data_len);

	unsigned char md32[4];
	bu_Hash4(md32, s->str, s->len);

	cstr_append_buf(s, md32, 4);

	cstring *s_enc = base58_encode(s->str, s->len);

	cstr_free(s, true);

	return s_enc;
}
Exemplo n.º 6
0
static void test_encode(const char *hexstr, const char *enc)
{
	size_t hs_len = strlen(hexstr) / 2;
	unsigned char *raw = calloc(1, hs_len);
	size_t out_len;

	bool rc = decode_hex(raw, hs_len, hexstr, &out_len);
	if (!rc) {
		fprintf(stderr, "raw %p, sizeof(raw) %lu, hexstr %p %s\n",
			raw, hs_len, hexstr, hexstr);
		assert(rc);
	}

	cstring *s = base58_encode(raw, out_len);
	if (strcmp(s->str, enc)) {
		fprintf(stderr, "base58 mismatch: '%s' vs expected '%s'\n",
			s->str, enc);
		assert(!strcmp(s->str, enc));
	}

	free(raw);
	cstr_free(s, true);
}
Exemplo n.º 7
0
static void print_n_base58(const void *data, size_t len)
{
	cstring *b58 = base58_encode(data, len);
	printf("%s", b58->str);
	cstr_free(b58, true);
}
Exemplo n.º 8
0
/* common dissector function for dissecting TFP payloads */
static void
dissect_tfp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

    gint   byte_offset = 0;
    gint   bit_offset  = 48;

    guint8 hv_tfp_len;
    guint8 hv_tfp_fid;
    guint8 hv_tfp_seq;

    gchar  tfp_uid_string[BASE58_MAX_STR_SIZE];

    base58_encode(tvb_get_letohl(tvb, 0), &tfp_uid_string[0]);

    hv_tfp_len = tvb_get_guint8(tvb, byte_offset_len);
    hv_tfp_fid = tvb_get_guint8(tvb, byte_offset_fid);
    hv_tfp_seq = tvb_get_bits8(tvb, bit_offset, bit_count_tfp_seq);

    col_add_fstr(pinfo->cinfo, COL_INFO,
                 "UID: %s, Len: %d, FID: %d, Seq: %d",
                 &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);

    /* call for details */
    if (tree) {
        proto_tree *tfp_tree;
        proto_item *ti;

        ti = proto_tree_add_protocol_format(tree, proto_tfp, tvb, 0, -1,
                                            "Tinkerforge Protocol, UID: %s, Len: %d, FID: %d, Seq: %d",
                                            &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);
        tfp_tree = proto_item_add_subtree(ti, ett_tfp);

        /* Use ...string_format_value() so we can show the complete generated string but specify */
        /*  the field length as being just the 4 bytes from which the string is generated.	 */
        ti = proto_tree_add_string_format_value(tfp_tree,
                                                hf_tfp_uid,
                                                tvb, byte_offset, byte_count_tfp_uid,
                                                &tfp_uid_string[0], "%s", &tfp_uid_string[0]);
        PROTO_ITEM_SET_GENERATED(ti);

        proto_tree_add_item(tfp_tree,
                            hf_tfp_uid_numeric,
                            tvb,
                            byte_offset,
                            byte_count_tfp_uid,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_uid;

        proto_tree_add_item(tfp_tree,
                            hf_tfp_len,
                            tvb,
                            byte_offset,
                            byte_count_tfp_len,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_len;

        proto_tree_add_item(tfp_tree,
                            hf_tfp_fid,
                            tvb,
                            byte_offset,
                            byte_count_tfp_fid,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_fid;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_seq,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_seq,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_seq;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_r,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_r,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_r;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_a,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_a,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_a;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_oo,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_oo,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_oo;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_e,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_e,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_e;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_future_use,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_future_use,
                                 ENC_LITTLE_ENDIAN);

        /*bit_offset += bit_count_tfp_future_use;*/

        if ((tvb_reported_length(tvb)) > 8) {

            byte_offset += byte_count_tfp_flags;

            proto_tree_add_item(tfp_tree, hf_tfp_payload, tvb, byte_offset, -1, ENC_NA);
        }
    }
}
Exemplo n.º 9
0
// If data should just be polled, set packet_send to NULL.
//
// If no packet is received from slave the length in packet_recv will be set to 0,
// the exact reason for that is encoded in the return value.
//
// For the return value see RED_STACK_TRANSCEIVE_RESULT_* at the top of this file.
static int red_stack_spi_transceive_message(REDStackPacket *packet_send, Packet *packet_recv, REDStackSlave *slave) {
	int retval = 0;
	uint8_t length, length_send;
	uint8_t checksum;
	int rc;
	uint8_t sequence_number_master = 0xFF;
	uint8_t sequence_number_slave = 0xFF;

	uint8_t tx[RED_STACK_SPI_PACKET_SIZE] = {0};
	uint8_t rx[RED_STACK_SPI_PACKET_SIZE] = {0};

	// We assume that we don't receive anything. If we receive a packet the
	// length will be overwritten again
	packet_recv->header.length = 0;

	// Preamble is always the same
	tx[RED_STACK_SPI_PREAMBLE] = RED_STACK_SPI_PREAMBLE_VALUE;

	if (packet_send == NULL) {
		// If packet_send is NULL
		// we send a message with empty payload (4 byte)
		tx[RED_STACK_SPI_LENGTH] = RED_STACK_SPI_PACKET_EMPTY_SIZE;
		retval = RED_STACK_TRANSCEIVE_RESULT_SEND_NONE;
	} else if (slave->status == RED_STACK_SLAVE_STATUS_AVAILABLE) {
		length = packet_send->packet.header.length;

		if (length > sizeof(Packet)) {
			retval |= RED_STACK_TRANSCEIVE_RESULT_SEND_ERROR;
			log_error("Send length is greater then allowed (actual: %d > maximum: %d)",
			          length, (int)sizeof(Packet));
			goto ret;
		}

		retval = RED_STACK_TRANSCEIVE_DATA_SEND;

		tx[RED_STACK_SPI_LENGTH] = length + RED_STACK_SPI_PACKET_EMPTY_SIZE;
		memcpy(tx+2, &packet_send->packet, length);
	} else {
		retval = RED_STACK_TRANSCEIVE_RESULT_SEND_ERROR;
		log_error("Slave with stack address %d is not present in stack", slave->stack_address);
		goto ret;
	}

	length = tx[RED_STACK_SPI_LENGTH];

	// Set master and slave sequence number
	tx[RED_STACK_SPI_INFO(length)] = slave->sequence_number_master | slave->sequence_number_slave;

	// Calculate checksum
	tx[RED_STACK_SPI_CHECKSUM(length)] = red_stack_spi_calculate_pearson_hash(tx, length-1);

	struct spi_ioc_transfer spi_transfer = {
		.tx_buf = (unsigned long)&tx,
		.rx_buf = (unsigned long)&rx,
		.len = RED_STACK_SPI_PACKET_SIZE,
	};

	red_stack_spi_select(slave);
	rc = ioctl(_red_stack_spi_fd, SPI_IOC_MESSAGE(1), &spi_transfer);
	red_stack_spi_deselect(slave);

	if (rc < 0) {
		// Overwrite current return status with error,
		// it seems ioctl itself didn't work.
		retval = RED_STACK_TRANSCEIVE_RESULT_SEND_ERROR | RED_STACK_TRANSCEIVE_RESULT_READ_ERROR;
		if(packet_send == NULL) {
			slave->next_packet_empty = true;
		}
		log_error("ioctl failed: %s (%d)", get_errno_name(errno), errno);
		goto ret;
	}

	length_send = rc;

	if (length_send != RED_STACK_SPI_PACKET_SIZE) {
		// Overwrite current return status with error,
		// it seems ioctl itself didn't work.
		retval = RED_STACK_TRANSCEIVE_RESULT_SEND_ERROR | RED_STACK_TRANSCEIVE_RESULT_READ_ERROR;
		if(packet_send == NULL) {
			slave->next_packet_empty = true;
		}
		log_error("ioctl has unexpected result (actual: %d != expected: %d)",
		          length_send, RED_STACK_SPI_PACKET_SIZE);
		goto ret;
	}

	if (rx[RED_STACK_SPI_PREAMBLE] != RED_STACK_SPI_PREAMBLE_VALUE) {
		// Do not log by default, an "unproper preamble" is part of the protocol
		// if the slave is too busy to fill the DMA buffers fast enough
		// log_error("Received packet without proper preamble (actual: %d != expected: %d)",
		//          rx[RED_STACK_SPI_PREAMBLE], RED_STACK_SPI_PREAMBLE_VALUE);
		retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_READ)) | RED_STACK_TRANSCEIVE_RESULT_READ_ERROR;
		if(packet_send == NULL) {
			slave->next_packet_empty = true;
		}
		goto ret;
	}

	// Check length
	length = rx[RED_STACK_SPI_LENGTH];

	if ((length != RED_STACK_SPI_PACKET_EMPTY_SIZE) &&
	    ((length < (RED_STACK_SPI_PACKET_EMPTY_SIZE + sizeof(PacketHeader))) ||
	     (length > RED_STACK_SPI_PACKET_SIZE))) {
		log_error("Received packet with malformed length: %d", length);
		retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_READ)) | RED_STACK_TRANSCEIVE_RESULT_READ_ERROR;
		if(packet_send == NULL) {
			slave->next_packet_empty = true;
		}
		goto ret;
	}

	// Calculate and check checksum
	checksum = red_stack_spi_calculate_pearson_hash(rx, length-1);

	if (checksum != rx[RED_STACK_SPI_CHECKSUM(length)]) {
		log_error("Received packet with wrong checksum (actual: %x != expected: %x)",
		          checksum, rx[RED_STACK_SPI_CHECKSUM(length)]);
		retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_READ)) | RED_STACK_TRANSCEIVE_RESULT_READ_ERROR;
		if(packet_send == NULL) {
			slave->next_packet_empty = true;
		}
		goto ret;
	}

	// If we send data and the master sequence number matches to the one
	// set in the packet we know that the slave received the packet!
	if ((packet_send != NULL) /*&& (packet_send->status == RED_STACK_PACKET_STATUS_SEQUENCE_NUMBER_SET)*/) {
		sequence_number_master = rx[RED_STACK_SPI_INFO(length)] & RED_STACK_SPI_INFO_SEQUENCE_MASTER_MASK;

		if (sequence_number_master == slave->sequence_number_master) {
			retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_SEND)) | RED_STACK_TRANSCEIVE_RESULT_SEND_OK;

			// Increase sequence number for next packet
			red_stack_increase_master_sequence_number(slave);
		}
	} else {
		// If we didn't send anything we can always increase the sequence number,
		// it doesn't matter if the slave actually received it.
		red_stack_increase_master_sequence_number(slave);
	}

	// If the slave sequence number matches we already processed this packet
	sequence_number_slave = rx[RED_STACK_SPI_INFO(length)] & RED_STACK_SPI_INFO_SEQUENCE_SLAVE_MASK;

	if (sequence_number_slave == slave->sequence_number_slave) {
		retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_READ)) | RED_STACK_TRANSCEIVE_RESULT_READ_NONE;
	} else {
		// Otherwise we save the new sequence number
		slave->sequence_number_slave = sequence_number_slave;

		if (length == RED_STACK_SPI_PACKET_EMPTY_SIZE) {
			// Do not log by default, will produce 2000 log entries per second
			// log_packet_debug("Received empty packet over SPI (w/ header)");
			retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_READ)) | RED_STACK_TRANSCEIVE_RESULT_READ_NONE;
		} else {
			// Everything seems OK, we can copy to buffer
			memcpy(packet_recv, rx+2, length - RED_STACK_SPI_PACKET_EMPTY_SIZE);
			log_packet_debug("Received packet over SPI (%s)",
			                 packet_get_response_signature(packet_signature, packet_recv));
			retval = (retval & (~RED_STACK_TRANSCEIVE_RESULT_MASK_READ)) | RED_STACK_TRANSCEIVE_RESULT_READ_OK;
			retval |= RED_STACK_TRANSCEIVE_DATA_RECEIVED;
		}
	}

ret:
	return retval;
}

// Creates the "routing table", which is just the
// array of REDStackSlave structures.
static void red_stack_spi_create_routing_table(void) {
	char base58[BASE58_MAX_LENGTH];
	int tries, ret, i;
	uint8_t stack_address = 0;
	uint8_t uid_counter = 0;

	log_debug("Starting to discover SPI stack slaves");

	while (stack_address < RED_STACK_SPI_MAX_SLAVES) {
		REDStackSlave *slave = &_red_stack.slaves[stack_address];

		Packet packet;
		StackEnumerateResponse *response;

		REDStackPacket red_stack_packet = {
			slave,
			{{
				0,   // UID 0
				sizeof(StackEnumerateRequest),
				FUNCTION_STACK_ENUMERATE,
				0x08, // Return expected
				0
			}, {0}, {0}},
			RED_STACK_PACKET_STATUS_ADDED,
		};

		// We have to assume that the slave is available
		slave->status = RED_STACK_SLAVE_STATUS_AVAILABLE;

		// Send stack enumerate request
		for (tries = 0; tries < RED_STACK_SPI_ROUTING_TRIES; tries++) {
			ret = red_stack_spi_transceive_message(&red_stack_packet, &packet, slave);

			if ((ret & RED_STACK_TRANSCEIVE_RESULT_MASK_SEND) == RED_STACK_TRANSCEIVE_RESULT_SEND_OK) {
				break;
			}

			SLEEP_NS(0, RED_STACK_SPI_ROUTING_WAIT); // Give slave some more time
		}

		if (tries == RED_STACK_SPI_ROUTING_TRIES) {
			// Slave does not seem to be available,
			slave->status = RED_STACK_SLAVE_STATUS_ABSENT;
			// This means that there can't be any more slaves above
			// and we are actually done here already!
			break;
		}

		// Receive stack enumerate response
		for (tries = 0; tries < RED_STACK_SPI_ROUTING_TRIES; tries++) {
			// We first check if we already received an answer before we try again
			if ((ret & RED_STACK_TRANSCEIVE_RESULT_MASK_READ) == RED_STACK_TRANSCEIVE_RESULT_READ_OK) {
				break;
			}

			// Here we sleep before transceive so that there is some time
			// between the sending of stack enumerate and the receiving
			// of the answer
			SLEEP_NS(0, RED_STACK_SPI_ROUTING_WAIT); // Give slave some more time

			ret = red_stack_spi_transceive_message(NULL, &packet, slave);
		}

		if (tries == RED_STACK_SPI_ROUTING_TRIES) {
			// Slave does not seem to be available,
			slave->status = RED_STACK_SLAVE_STATUS_ABSENT;
			// This means that there can't be any more slaves above
			// and we are actually done here already!
			break;
		}

		response = (StackEnumerateResponse *)&packet;

		for (i = 0; i < PACKET_MAX_STACK_ENUMERATE_UIDS; i++) {
			if (response->uids[i] != 0) {
				uid_counter++;
				stack_add_recipient(&_red_stack.base, response->uids[i], stack_address);
				log_debug("Found UID number %d of slave %d with UID %s",
				          i, stack_address,
				          base58_encode(base58, uint32_from_le(response->uids[i])));
			} else {
				break;
			}
		}

		stack_address++;
	}

	_red_stack.slave_num = stack_address;

	log_info("SPI stack slave discovery done. Found %d slave(s) with %d UID(s) in total",
	         stack_address, uid_counter);
}
Exemplo n.º 10
0
/* creates a bitcoin address+private key from the SHA256
 *  hash of string. converts to base58 if base58 is 'true'
 *  returns 1 if successful, 0 if not*/
int create_address_from_string(const unsigned char *string,
		unsigned char *address,
		unsigned char *priv_key,
		EC_GROUP *precompgroup,
		bool base58,
		bool debug) {

    u_int8_t * hash = malloc(SHA256_DIGEST_LENGTH);
    BIGNUM * n = BN_new();

    //first we hash the string
    SHA256 (string, strlen(string), hash);
	//then we convert the hash to the BIGNUM n
    n = BN_bin2bn(hash, SHA256_DIGEST_LENGTH, n);

    BIGNUM * order = BN_new();
    BIGNUM * nmodorder = BN_new();
	BN_CTX *bnctx;
	bnctx = BN_CTX_new();

    //then we create a new EC group with the curve secp256k1
	EC_GROUP * pgroup;
	pgroup = EC_GROUP_new_by_curve_name(NID_secp256k1);

    if (!pgroup) {
    	printf("ERROR: Couldn't get new group\n");
    	return 0;
    }

    //now we need to get the order of the group, and make sure that
    //the number we use for the private key is less than or equal to
    //the group order by using "nmodorder = n % order"
    EC_GROUP_get_order(pgroup, order, NULL);
    BN_mod(nmodorder, n, order, bnctx);

    if (BN_is_zero(nmodorder)) {
    	printf("ERROR: SHA256(string) % order == 0. Pick another string.\n");
    	return 0;
    }

    if (debug)
    	printf ("Secret number: %s\n", BN_bn2dec(nmodorder));

    //now we create a new EC point, ecpoint, and place in it the secp256k1
    //generator point multiplied by nmodorder. this newly created
    //point is the public key

    EC_POINT * ecpoint = EC_POINT_new(pgroup);

	if (!EC_POINT_mul(pgroup, ecpoint, nmodorder, NULL, NULL, NULL))
	{
    	printf("ERROR: Couldn't multiply the generator point with n\n");
    	return 0;
    }


    if (debug) {
        BIGNUM *x=NULL, *y=NULL;
        x=BN_new();
        y=BN_new();

        if (!EC_POINT_get_affine_coordinates_GFp(pgroup, ecpoint, x, y, NULL)) {
        	printf("ERROR: Failed getting coordinates.");
        	//don't fail on debug fail
        	//return 0;
        }

    	printf ("Public key coordinates. x: %s, y: %s\n", BN_bn2dec(x), BN_bn2dec(y));

        BN_free(x);
        BN_free(y);
    }

    //then we need to convert the public key point to data
    //first we get the required size of the buffer in which the data is placed
    //by passing NULL as the buffer argument to EC_POINT_point2oct
    unsigned int bufsize = EC_POINT_point2oct (pgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
    u_int8_t * buffer = malloc(bufsize);
    //then we place the data in the buffer
    int len = EC_POINT_point2oct (pgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buffer, bufsize, NULL);
    if (len == 0) {
    	printf("ERROR: Couldn't convert point to octet string.");
    	return 0;
    }

    if (debug) {
    	printf("DER encoded public key: ");
    	print_hex(buffer, len);
    }

    //next we need to hash the public key data. first with SHA256, then with RIPEMD160
    SHA256(buffer, len, hash);
    if (debug) {
    	printf("SHA256 hash of public key: ");
    	print_hex(hash, SHA256_DIGEST_LENGTH);
    }

    u_int8_t * ripemd = malloc(RIPEMD160_DIGEST_LENGTH+1+4);
    RIPEMD160(hash, SHA256_DIGEST_LENGTH, ripemd);

    if (debug) {
    	printf("RIPEMD160 hash of SHA256 hash: ");
    	print_hex(ripemd, RIPEMD160_DIGEST_LENGTH);
    }

    if (base58 == true) {
		//here we add the version byte to the beginning of the public key and four checksum
		//bytes at the end
		prepare_for_address(ripemd, RIPEMD160_DIGEST_LENGTH, 0);

		if (debug) {
			printf("Address in hex with version byte and checksum: ");
			print_hex(ripemd, RIPEMD160_DIGEST_LENGTH+1+4);
		}

		//and we convert the resulting data to base58
		base58_encode(ripemd, RIPEMD160_DIGEST_LENGTH+1+4, address);
    } else {
    	memcpy(address, ripemd, RIPEMD160_DIGEST_LENGTH);
    }

    //now we need to convert the big number nmodorder (private key) to data
    int buflen = BN_num_bytes(nmodorder);
    u_int8_t * buf = malloc(buflen+1+4);
    int datalen;

    //nmodorder is converted to binary representation
    datalen = BN_bn2bin(nmodorder, buf);

    if (debug) {
    	printf("Private key: ");
    	print_hex(buf, datalen);
    }

    if (base58 == true) {
		//and we add version byte and four byte checksum to the data
		prepare_for_address(buf, datalen, 0x80);

        //and convert this to base58
        base58_encode(buf, datalen+5, priv_key);
    } else {
    	memcpy(priv_key, buf, datalen+5);
    }

    free(hash);
    free(buffer);
    free(ripemd);
    free(buf);
    BN_free(n);
    BN_free(order);
    BN_free(nmodorder);
    if (precompgroup == NULL)
    	EC_GROUP_free(pgroup);
    EC_POINT_free(ecpoint);
    BN_CTX_free(bnctx);

    return 1;
}
Exemplo n.º 11
0
// New packet from BrickletStack is send into brickd event loop
static void bricklet_stack_dispatch_from_spi(void *opaque) {
	BrickletStack *bricklet_stack = (BrickletStack*)opaque;
	int i;
	eventfd_t ev;
	Packet *packet;

	(void)opaque;

	// handle at most 5 queued responses at once to avoid blocking the event
	// loop for too long
	for (i = 0; i < 5; ++i) {
		if (eventfd_read(bricklet_stack->notification_event, &ev) < 0) {
			if (errno_would_block()) {
				return; // no queue responses left
			}

			log_error("Could not read from SPI notification event: %s (%d)",
			          get_errno_name(errno), errno);

			return;
		}

		mutex_lock(&bricklet_stack->response_queue_mutex);
		packet = queue_peek(&bricklet_stack->response_queue);
		mutex_unlock(&bricklet_stack->response_queue_mutex);

		if (packet == NULL) { // eventfd indicates a response but queue is empty
			log_error("Response queue and notification event are out-of-sync");

			return;
		}

		// Update routing table (this is necessary for Co-MCU Bricklets)
		if (packet->header.function_id == CALLBACK_ENUMERATE) {
			stack_add_recipient(&bricklet_stack->base, packet->header.uid, 0);
		}

		if ((packet->header.function_id == CALLBACK_ENUMERATE) ||
		    (packet->header.function_id == FUNCTION_GET_IDENTITY)) {
			EnumerateCallback *ec = (EnumerateCallback*)packet;

			// If the Bricklet is a HAT Brick (ID 111) or HAT Zero Brick (ID 112)
			// we update the connected_uid.
			if((ec->device_identifier == 111) || (ec->device_identifier == 112)) {
				*bricklet_stack->config.connected_uid = ec->header.uid;
			}

			// If the Bricklet is connected to an isolator we don't have to
			// update the position and the connected UID. this is already
			// done by the isolator itself.
			if(ec->position != 'Z' || ec->connected_uid[0] == '\0') {
				memcpy(ec->connected_uid, PACKET_NO_CONNECTED_UID_STR, PACKET_NO_CONNECTED_UID_STR_LENGTH);
				if((*bricklet_stack->config.connected_uid != 0) && (ec->device_identifier != 111) && (ec->device_identifier != 112)) {
					char base58[BASE58_MAX_LENGTH];
					base58_encode(base58, uint32_from_le(*bricklet_stack->config.connected_uid));
					strncpy(ec->connected_uid, base58, BASE58_MAX_LENGTH);
				}

				ec->position = 'a' + bricklet_stack->config.num;
			}
		}

		// Send message into brickd dispatcher
		network_dispatch_response(packet);
		bricklet_stack->data_seen = true;

		mutex_lock(&bricklet_stack->response_queue_mutex);
		queue_pop(&bricklet_stack->response_queue, NULL);
		mutex_unlock(&bricklet_stack->response_queue_mutex);
	}
}
Exemplo n.º 12
0
std::string CoinKey::to_str()const
{
	std::string str = base58_encode(&m_data, sizeof(m_data));
	return str;
}