TEST(atcacert_der_enc_length, atcacert_der_enc_length__short_form)
{
	uint32_t length;
	uint8_t der_length[8];
	size_t der_length_size = sizeof(der_length);
	int ret = 0;

	// Smallest shot form
	length = 0x00;
	der_length_size = sizeof(der_length);
	ret = atcacert_der_enc_length(length, der_length, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
	TEST_ASSERT_EQUAL(1, der_length_size);
	TEST_ASSERT_EQUAL(length, der_length[0]);

	// Largest short form
	length = 0x7F;
	der_length_size = sizeof(der_length);
	ret = atcacert_der_enc_length(length, der_length, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
	TEST_ASSERT_EQUAL(1, der_length_size);
	TEST_ASSERT_EQUAL(length, der_length[0]);

	// Size only
	length = 127;
	der_length_size = 0;
	ret = atcacert_der_enc_length(length, NULL, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
	TEST_ASSERT_EQUAL(1, der_length_size);
}
TEST(atcacert_der_enc_length, atcacert_der_enc_length__long_form_2byte)
{
    uint32_t length;
	uint8_t der_len_min[] = { 0x81, 0x80 }; // 0x80
	uint8_t der_len_max[] = { 0x81, 0xFF }; // 0xFF
	uint8_t der_length[8];
	size_t der_length_size = sizeof(der_length);
	int ret = 0;

	// Smallest 2-byte long form
	length = 0x80;
	der_length_size = sizeof(der_length);
	ret = atcacert_der_enc_length(length, der_length, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
	TEST_ASSERT_EQUAL(sizeof(der_len_min), der_length_size);
	TEST_ASSERT_EQUAL_MEMORY(der_len_min, der_length, sizeof(der_len_min));

	// Largest 2-byte long form
	length = 0xFF;
	der_length_size = sizeof(der_length);
	ret = atcacert_der_enc_length(length, der_length, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
	TEST_ASSERT_EQUAL(sizeof(der_len_max), der_length_size);
	TEST_ASSERT_EQUAL_MEMORY(der_len_max, der_length, sizeof(der_len_max));

	// Size only
	length = 0xFF;
	der_length_size = 0;
	ret = atcacert_der_enc_length(length, NULL, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
	TEST_ASSERT_EQUAL(sizeof(der_len_max), der_length_size);
}
Example #3
0
int atcacert_der_adjust_length(uint8_t* der_length, size_t* der_length_size, int delta_length, uint32_t* new_length)
{
    int ret = 0;
    size_t new_der_len_size = 0;
    uint32_t old_len = 0;
    uint32_t new_len = 0;
    uint8_t new_der_length[5];
    
	ret = atcacert_der_dec_length(der_length, der_length_size, &old_len);
	if (ret != ATCACERT_E_SUCCESS)
		return ret;
    
    if (delta_length < 0 && (size_t)(-delta_length) > old_len)
        return ATCACERT_E_ERROR;
    new_len = old_len + delta_length;
    
    if (new_length != NULL)
        *new_length = new_len;
    
	new_der_len_size = sizeof(new_der_length);
	ret = atcacert_der_enc_length(new_len, new_der_length, &new_der_len_size);
	if (ret != ATCACERT_E_SUCCESS)
		return ret;

	if (*der_length_size != new_der_len_size)
		return ATCACERT_E_BAD_CERT;

	memcpy(der_length, new_der_length, new_der_len_size);
    
    return 0;
}
TEST(atcacert_der_enc_length, atcacert_der_enc_length__bad_params)
{
    uint32_t length;
	uint8_t der_length[8];
	int ret = 0;

	length = 0x01000000;
	ret = atcacert_der_enc_length(length, der_length, NULL);
	TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret);
}
TEST(atcacert_der_enc_length, atcacert_der_enc_length__small_buf)
{
    uint32_t length;
	uint8_t der_length[3];
	size_t der_length_size = sizeof(der_length);
	int ret = 0;

	length = 0x01000000;
	der_length_size = sizeof(der_length);
	ret = atcacert_der_enc_length(length, der_length, &der_length_size);
	TEST_ASSERT_EQUAL(ATCACERT_E_BUFFER_TOO_SMALL, ret);
	TEST_ASSERT_EQUAL(5, der_length_size);
}
Example #6
0
int atcacert_der_enc_integer( const uint8_t* int_data,
                              size_t int_data_size,
                              uint8_t is_unsigned,
                              uint8_t*       der_int,
                              size_t*        der_int_size)
{
	uint8_t der_length[5];
	size_t der_length_size = sizeof(der_length);
	size_t der_int_size_calc = 0;
	size_t trim = 0;
	size_t pad = 0;

	if (int_data == NULL || der_int_size == NULL || int_data_size <= 0)
		return ATCACERT_E_BAD_PARAMS;

	if (!(is_unsigned && (int_data[0] & 0x80))) {
		// This is not an unsigned value that needs a padding byte, trim any unnecessary bytes.
		// Trim a byte when the upper 9 bits are all 0s or all 1s.
		while (
		    (int_data_size - trim >= 2) && (
		        ((int_data[trim] == 0x00) && ((int_data[trim + 1] & 0x80) == 0)) ||
		        ((int_data[trim] == 0xFF) && ((int_data[trim + 1] & 0x80) != 0))))
			trim++;
	}else
		// Will be adding extra byte for unsigned padding so it's not interpreted as negative
		pad = 1;

	int ret = atcacert_der_enc_length(int_data_size + pad - trim, der_length, &der_length_size);
	if (ret != ATCACERT_E_SUCCESS)
		return ret;

	der_int_size_calc = 1 + der_length_size + int_data_size + pad - trim;

	if (der_int != NULL && der_int_size_calc > *der_int_size) {
		*der_int_size = der_int_size_calc;
		return ATCACERT_E_BUFFER_TOO_SMALL;
	}

	*der_int_size = der_int_size_calc;

	if (der_int == NULL)
		return ATCACERT_E_SUCCESS;                                                      // Caller just wanted the size of the encoded integer

	der_int[0] = 0x02;                                                                  // Integer tag
	memcpy(&der_int[1], der_length, der_length_size);                                   // Integer length
	if (pad)
		der_int[der_length_size + 1] = 0;                                               // Unsigned integer value requires padding byte so it's not interpreted as negative
	memcpy(&der_int[der_length_size + 1 + pad], &int_data[trim], int_data_size - trim); // Integer value

	return ATCACERT_E_SUCCESS;
}
int atcacert_set_signature( const atcacert_def_t* cert_def,
                            uint8_t*              cert,
                            size_t*               cert_size,
                            size_t max_cert_size,
                            const uint8_t signature[64])
{
	int ret = 0;
	uint16_t sig_offset;
	size_t cur_der_sig_size;
	size_t new_der_sig_size;
	size_t old_cert_der_length_size;
	size_t new_cert_der_length_size;
	size_t new_cert_length;
	uint8_t new_cert_der_length[5];

	if (cert_def == NULL || cert == NULL || cert_size == NULL || signature == NULL)
		return ATCACERT_E_BAD_PARAMS;

	sig_offset = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset;

	// Non X.509 signatures are treated like normal certificate elements
	if (cert_def->type != CERTTYPE_X509)
		return atcacert_set_cert_element(&cert_def->std_cert_elements[STDCERT_SIGNATURE], cert, *cert_size, signature, 64);

	if (sig_offset >= *cert_size)
		return ATCACERT_E_ELEM_OUT_OF_BOUNDS; // Signature element is shown as past the end of the certificate

	// Current size of the signature is from its offset to the end of the cert
	cur_der_sig_size = *cert_size - sig_offset;

	// Find the size of buffer available for the new DER signature
	new_der_sig_size = max_cert_size - sig_offset;

	// Set the new signature
	ret = atcacert_der_enc_ecdsa_sig_value(signature, &cert[sig_offset], &new_der_sig_size);
	if (ret != ATCACERT_E_SUCCESS) {
		if (ret == ATCACERT_E_BUFFER_TOO_SMALL)
			*cert_size += (int)new_der_sig_size - (int)cur_der_sig_size; // Report the size needed
		return ret;
	}

	*cert_size += (int)new_der_sig_size - (int)cur_der_sig_size;

	old_cert_der_length_size = *cert_size - 1;
	ret = atcacert_der_dec_length(&cert[1], &old_cert_der_length_size, NULL);
	if (ret != ATCACERT_E_SUCCESS)
		return ret;

	if ((1 + old_cert_der_length_size) > *cert_size)
		return ATCACERT_E_BAD_CERT;
	new_cert_length = *cert_size - (1 + old_cert_der_length_size);

	new_cert_der_length_size = sizeof(new_cert_der_length);
	ret = atcacert_der_enc_length(new_cert_length, new_cert_der_length, &new_cert_der_length_size);
	if (ret != ATCACERT_E_SUCCESS)
		return ret;

	if (old_cert_der_length_size != new_cert_der_length_size)
		return ATCACERT_E_BAD_CERT;

	memcpy(&cert[1], new_cert_der_length, new_cert_der_length_size);

	return ATCACERT_E_SUCCESS;
}