Exemplo n.º 1
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_dec_length, atcacert_der_dec_der_length__bad_params)
{
	int ret = 0;
	const uint8_t der_length[] = { 0x82, 0x01, 0x0 };
	size_t der_length_size = sizeof(der_length);
    uint32_t length = 0;

	der_length_size = sizeof(der_length);
	ret = atcacert_der_dec_length(NULL, &der_length_size, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret);

	der_length_size = sizeof(der_length);
	ret = atcacert_der_dec_length(der_length, NULL, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret);

	ret = atcacert_der_dec_length(NULL, NULL, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret);
}
TEST(atcacert_der_dec_length, atcacert_der_dec_der_length__too_large)
{
	int ret = 0;
	const uint8_t der_length[] = { 0x89, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; // Too large for the return type (64 bit size_t)
	size_t der_length_size = sizeof(der_length);
    uint32_t length = 0;

	ret = atcacert_der_dec_length(der_length, &der_length_size, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_DECODING_ERROR, ret);
}
TEST(atcacert_der_dec_length, atcacert_der_dec_der_length__indefinite_form)
{
	int ret = 0;
	const uint8_t der_length[] = { 0x80, 0x01 }; // Indefinite form not supported
	size_t der_length_size = sizeof(der_length);
    uint32_t length = 0;

	ret = atcacert_der_dec_length(der_length, &der_length_size, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_DECODING_ERROR, ret);
}
TEST(atcacert_der_dec_length, atcacert_der_dec_der_length__not_enough_data)
{
	int ret = 0;
	const uint8_t der_length[] = { 0x82, 0x01 }; // Encoding indicates more data than is supplied
	size_t der_length_size = sizeof(der_length);
    uint32_t length = 0;

	ret = atcacert_der_dec_length(der_length, &der_length_size, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_DECODING_ERROR, ret);
}
TEST(atcacert_der_dec_length, atcacert_der_dec_der_length__zero_size)
{
	int ret = 0;
	const uint8_t der_length[] = { 0x00 }; // Just needed for a valid pointer
	size_t der_length_size = 0;
    uint32_t length = 0;

	ret = atcacert_der_dec_length(der_length, &der_length_size, &length);
	TEST_ASSERT_EQUAL(ATCACERT_E_DECODING_ERROR, ret);
}
TEST(atcacert_der_dec_length, atcacert_der_dec_der_length__good)
{
	int ret = 0;
	size_t i;
	const struct atcacert_der_dec_length__good_s tests[] = {
		{ 0x00000000, 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
		{ 0x0000003F, 1, { 0x3F, 0x00, 0x00, 0x00, 0x00 } },
		{ 0x0000007F, 1, { 0x7F, 0x00, 0x00, 0x00, 0x00 } },
		{ 0x00000080, 2, { 0x81, 0x80, 0x00, 0x00, 0x00 } },
		{ 0x00000085, 2, { 0x81, 0x85, 0x00, 0x00, 0x00 } },
		{ 0x000000FF, 2, { 0x81, 0xFF, 0x00, 0x00, 0x00 } },
		{ 0x00000100, 3, { 0x82, 0x01, 0x00, 0x00, 0x00 } },
		{ 0x000055AA, 3, { 0x82, 0x55, 0xAA, 0x00, 0x00 } },
		{ 0x0000FFFF, 3, { 0x82, 0xFF, 0xFF, 0x00, 0x00 } },
		{ 0x00010000, 4, { 0x83, 0x01, 0x00, 0x00, 0x00 } },
		{ 0x0055AA55, 4, { 0x83, 0x55, 0xAA, 0x55, 0x00 } },
		{ 0x00FFFFFF, 4, { 0x83, 0xFF, 0xFF, 0xFF, 0x00 } },
		{ 0x01000000, 5, { 0x84, 0x01, 0x00, 0x00, 0x00 } },
		{ 0x55AA55AA, 5, { 0x84, 0x55, 0xAA, 0x55, 0xAA } },
		{ 0xFFFFFFFF, 5, { 0x84, 0xFF, 0xFF, 0xFF, 0xFF } },
	};

	for (i = 0; i < sizeof(tests) / sizeof(struct atcacert_der_dec_length__good_s); i++) {
		size_t der_length_size = sizeof(tests[i].der_length);
        uint32_t length = 0;
		ret = atcacert_der_dec_length(tests[i].der_length, &der_length_size, &length);
		TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
		TEST_ASSERT_EQUAL(tests[i].der_length_size, der_length_size);
		TEST_ASSERT_EQUAL(tests[i].length, length);

		// Size only
		der_length_size = sizeof(tests[i].der_length);
		ret = atcacert_der_dec_length(tests[i].der_length, &der_length_size, NULL);
		TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret);
		TEST_ASSERT_EQUAL(tests[i].der_length_size, der_length_size);
	}
}
Exemplo n.º 8
0
int atcacert_der_dec_integer( const uint8_t* der_int,
                              size_t*        der_int_size,
                              uint8_t*       int_data,
                              size_t*        int_data_size)
{
	int ret = 0;
	size_t der_length_size = 0;
	uint32_t int_data_size_calc = 0;

	if (der_int == NULL || der_int_size == NULL || (int_data != NULL && int_data_size == NULL))
		return ATCACERT_E_BAD_PARAMS;

	if (*der_int_size < 1)
		return ATCACERT_E_DECODING_ERROR; // No data to decode

	if (der_int[0] != 0x02)
		return ATCACERT_E_DECODING_ERROR; // Not an integer tag

	der_length_size = *der_int_size - 1;
	ret = atcacert_der_dec_length(&der_int[1], &der_length_size, &int_data_size_calc);
	if (ret != ATCACERT_E_SUCCESS)
		return ret;

	if (*der_int_size < (1 + der_length_size + int_data_size_calc))
		return ATCACERT_E_DECODING_ERROR; // Invalid DER integer, not enough data.

	*der_int_size = (1 + der_length_size + int_data_size_calc);

	if (int_data == NULL && int_data_size == NULL)
		return ATCACERT_E_SUCCESS; // Caller doesn't want the actual data, just the der_int_size

	if (int_data != NULL && *int_data_size < int_data_size_calc) {
		*int_data_size = int_data_size_calc;
		return ATCACERT_E_BUFFER_TOO_SMALL;
	}

	*int_data_size = int_data_size_calc;

	if (int_data == NULL)
		return ATCACERT_E_SUCCESS; // Caller doesn't want the actual data, just the int_data_size

	memcpy(int_data, &der_int[1 + der_length_size], int_data_size_calc);

	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;
}
Exemplo n.º 10
0
int atcacert_der_dec_ecdsa_sig_value( const uint8_t* der_sig,
                                      size_t*        der_sig_size,
                                      uint8_t raw_sig[64])
{
	int ret = 0;
	size_t curr_idx = 0;
	size_t dec_size = 0;
	uint32_t bs_length = 0;
	uint32_t seq_length = 0;
	size_t r_size = 0;
	size_t s_size = 0;
	uint8_t int_data[33];
	size_t int_data_size = 0;

	if (der_sig == NULL || der_sig_size == NULL)
		return ATCACERT_E_BAD_PARAMS;

	if (*der_sig_size < 1)
		return ATCACERT_E_DECODING_ERROR; // No data to decode

	// signatureValue bit string tag
	curr_idx = 0;
	if (der_sig[curr_idx] != 0x03)
		return ATCACERT_E_DECODING_ERROR; // Unexpected tag value
	curr_idx++;

	// signatureValue bit string length
	dec_size = *der_sig_size - curr_idx;
	ret = atcacert_der_dec_length(&der_sig[curr_idx], &dec_size, &bs_length);
	if (ret != ATCACERT_E_SUCCESS)
		return ret; // Failed to decode length
	curr_idx += dec_size;
	if (curr_idx + bs_length > *der_sig_size)
		return ATCACERT_E_DECODING_ERROR; // Not enough data in buffer to decode the rest

	// signatureValue bit string spare bits
	if (curr_idx >= *der_sig_size)
		return ATCACERT_E_DECODING_ERROR;   // No data left
	if (der_sig[curr_idx] != 0x00)
		return ATCACERT_E_DECODING_ERROR;   // Unexpected spare bits value
	curr_idx++;

	// signatureValue bit string value is the DER encoding of ECDSA-Sig-Value

	// sequence tag
	if (curr_idx >= *der_sig_size)
		return ATCACERT_E_DECODING_ERROR;   // No data left
	if (der_sig[curr_idx] != 0x30)
		return ATCACERT_E_DECODING_ERROR;   // Unexpected tag value
	curr_idx++;

	// sequence length
	if (curr_idx >= *der_sig_size)
		return ATCACERT_E_DECODING_ERROR; // No data left
	dec_size = *der_sig_size - curr_idx;
	ret = atcacert_der_dec_length(&der_sig[curr_idx], &dec_size, &seq_length);
	if (ret != ATCACERT_E_SUCCESS)
		return ret; // Failed to decode length
	curr_idx += dec_size;
	if (curr_idx + seq_length > *der_sig_size)
		return ATCACERT_E_DECODING_ERROR; // Not enough data in buffer to decode the rest

	// R integer
	if (curr_idx >= *der_sig_size)
		return ATCACERT_E_DECODING_ERROR; // No data left
	r_size = *der_sig_size - curr_idx;
	int_data_size = sizeof(int_data);
	ret = atcacert_der_dec_integer(&der_sig[curr_idx], &r_size, int_data, &int_data_size);
	if (ret != ATCACERT_E_SUCCESS)
		return ret; // Failed to decode length
	curr_idx += r_size;

	if (raw_sig != NULL)
		memset(raw_sig, 0, 64); // Zero out the raw sig as the decoded integers may not touch all bytes

	if (int_data_size <= 32) {
		if (raw_sig != NULL)
			memcpy(&raw_sig[32 - int_data_size], &int_data[0], int_data_size);
	}else if (int_data_size == 33) {
		if (int_data[0] != 0x00)
			return ATCACERT_E_DECODING_ERROR; // R integer is too large
		// DER integer was 0-padded to keep it positive
		if (raw_sig != NULL)
			memcpy(&raw_sig[0], &int_data[1], 32);
	}else
		return ATCACERT_E_DECODING_ERROR; // R integer is too large

	// S integer
	if (curr_idx >= *der_sig_size)
		return ATCACERT_E_DECODING_ERROR; // No data left
	s_size = *der_sig_size - curr_idx;
	int_data_size = sizeof(int_data);
	ret = atcacert_der_dec_integer(&der_sig[curr_idx], &s_size, int_data, &int_data_size);
	if (ret != ATCACERT_E_SUCCESS)
		return ret; // Failed to decode length
	curr_idx += s_size;

	if (int_data_size <= 32) {
		if (raw_sig != NULL)
			memcpy(&raw_sig[64 - int_data_size], &int_data[0], int_data_size);
	}else if (int_data_size == 33) {
		if (int_data[0] != 0x00)
			return ATCACERT_E_DECODING_ERROR; // S integer is too large
		// DER integer was 0-padded to keep it positive
		if (raw_sig != NULL)
			memcpy(&raw_sig[32], &int_data[1], 32);
	}else
		return ATCACERT_E_DECODING_ERROR; // S integer is too large

	if (seq_length != r_size + s_size)
		return ATCACERT_E_DECODING_ERROR; // Unexpected extra data in sequence

	if (bs_length != r_size + s_size + 3)
		return ATCACERT_E_DECODING_ERROR; // Unexpected extra data in bit string

	*der_sig_size = curr_idx;

	return ATCACERT_E_SUCCESS;
}