corecrypto/ccder/crypto_test/crypto_test_der.c

571 lines
24 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Copyright (c) (2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef CCDER_MULTIBYTE_TAGS
#define CCDER_MULTIBYTE_TAGS 1
#endif // CCDER_MULTIBYTE_TAGS
#include "testmore.h"
#include "testbyteBuffer.h"
#include "crypto_test_der.h"
#include <corecrypto/ccder.h>
#if (CCDER == 0)
entryPoint(ccder_tests, "ccder")
#else
//============================= ccder_sizeof ===================================
static void testSizeOf()
{
is(ccder_sizeof(CCDER_EOL, 0), (size_t)2, "EOL");
is(ccder_sizeof(CCDER_BOOLEAN, 0), (size_t)2, "BOOLEAN");
is(ccder_sizeof(CCDER_INTEGER, 0), (size_t)2, "INTEGER");
is(ccder_sizeof(CCDER_BIT_STRING, 0), (size_t)2, "BIT_STRING");
is(ccder_sizeof(CCDER_OCTET_STRING, 0), (size_t)2, "OCTET_STRING");
is(ccder_sizeof(CCDER_NULL, 0), (size_t)2, "NULL");
is(ccder_sizeof(CCDER_OBJECT_IDENTIFIER, 0), (size_t)2, "OBJECT_IDENTIFIER");
is(ccder_sizeof(CCDER_REAL, 0), (size_t)2, "REAL");
is(ccder_sizeof(CCDER_ENUMERATED, 0), (size_t)2, "ENUMERATED");
is(ccder_sizeof(CCDER_EMBEDDED_PDV, 0), (size_t)2, "EMBEDDED_PDV");
is(ccder_sizeof(CCDER_UTF8_STRING, 0), (size_t)2, "UTF8_STRING");
is(ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, 0), (size_t)2, "CONSTRUCTED_SEQUENCE");
is(ccder_sizeof(CCDER_CONSTRUCTED_SET, 0), (size_t)2, "CONSTRUCTED_SET");
is(ccder_sizeof(CCDER_NUMERIC_STRING, 0), (size_t)2, "NUMERIC_STRING");
is(ccder_sizeof(CCDER_PRINTABLE_STRING, 0), (size_t)2, "PRINTABLE_STRING");
is(ccder_sizeof(CCDER_T61_STRING, 0), (size_t)2, "T61_STRING");
is(ccder_sizeof(CCDER_VIDEOTEX_STRING, 0), (size_t)2, "VIDEOTEX_STRING");
is(ccder_sizeof(CCDER_IA5_STRING, 0), (size_t)2, "IA5_STRING");
is(ccder_sizeof(CCDER_UTC_TIME, 0), (size_t)2, "UTC_TIME");
is(ccder_sizeof(CCDER_GENERALIZED_TIME, 0), (size_t)2, "GENERALIZED_TIME");
is(ccder_sizeof(CCDER_GRAPHIC_STRING, 0), (size_t)2, "GRAPHIC_STRING");
is(ccder_sizeof(CCDER_VISIBLE_STRING, 0), (size_t)2, "VISIBLE_STRING");
is(ccder_sizeof(CCDER_GENERAL_STRING, 0), (size_t)2, "GENERAL_STRING");
is(ccder_sizeof(CCDER_UNIVERSAL_STRING, 0), (size_t)2, "UNIVERSAL_STRING");
is(ccder_sizeof(CCDER_BMP_STRING, 0), (size_t)2, "BMP_STRING");
is(ccder_sizeof(CCDER_HIGH_TAG_NUMBER, 0), (size_t)3, "HIGH_TAG_NUMBER");
is(ccder_sizeof(0x1f, 0), (size_t)3, "[31]");
is(ccder_sizeof(0x20, 0), (size_t)3, "[32]");
is(ccder_sizeof(0x7f, 0), (size_t)3, "[127]");
is(ccder_sizeof(0x80, 0), (size_t)4, "[128]");
is(ccder_sizeof(0x3fff, 0), (size_t)4, "[4095]");
is(ccder_sizeof(0x4000, 0), (size_t)5, "[4096]");
is(ccder_sizeof(0x1fffff, 0), (size_t)5, "[2097151]");
is(ccder_sizeof(0x200000, 0), (size_t)6, "[2097152]");
is(ccder_sizeof(CCDER_OCTET_STRING, 1), (size_t)3, "OCTET_STRING(1)");
is(ccder_sizeof(CCDER_OCTET_STRING, 127), (size_t)129, "OCTET_STRING(127)");
is(ccder_sizeof(CCDER_OCTET_STRING, 128), (size_t)131, "OCTET_STRING(128)");
is(ccder_sizeof(CCDER_OCTET_STRING, 128), (size_t)131, "OCTET_STRING(129)");
}
//============================= ccder_sizeof_uint64 ============================
static void testSizeOfUInt64()
{
is(ccder_sizeof_uint64(0), (size_t)3, "uint64(0)");
is(ccder_sizeof_uint64(1), (size_t)3, "uint64(1)");
is(ccder_sizeof_uint64(0x7f), (size_t)3, "uint64(0x7f)");
is(ccder_sizeof_uint64(0x80), (size_t)4, "uint64(0x80)");
is(ccder_sizeof_uint64(0x100), (size_t)4, "uint64(0x100)");
is(ccder_sizeof_uint64(0x7fff), (size_t)4, "uint64(0x7fff)");
is(ccder_sizeof_uint64(0x8000), (size_t)5, "uint64(0x8000)");
is(ccder_sizeof_uint64(0x7fffff), (size_t)5, "uint64(0x7fffff)");
is(ccder_sizeof_uint64(0x800000), (size_t)6, "uint64(0x800000)");
is(ccder_sizeof_uint64(0x7fffffff), (size_t)6, "uint64(0x7fffffff)");
is(ccder_sizeof_uint64(0x80000000), (size_t)7, "uint64(0x80000000)");
is(ccder_sizeof_uint64(0x7fffffffff), (size_t)7, "uint64(0x7fffffffff)");
is(ccder_sizeof_uint64(0x8000000000), (size_t)8, "uint64(0x8000000000)");
is(ccder_sizeof_uint64(0x7fffffffffff), (size_t)8, "uint64(0x7fffffffffff)");
is(ccder_sizeof_uint64(0x800000000000), (size_t)9, "uint64(0x800000000000)");
is(ccder_sizeof_uint64(0x7fffffffffffff), (size_t)9, "uint64(0x7fffffffffffff)");
is(ccder_sizeof_uint64(0x80000000000000), (size_t)10, "uint64(0x80000000000000)");
is(ccder_sizeof_uint64(0x7fffffffffffffff), (size_t)10, "uint64(0x7fffffffffffffff)");
}
//================================ ccder_encode_tag ============================
static void testEncodeTag(void)
{
// These define the length bounds for tags
unsigned long limits[] = {0x7f, 0x3fff, 0x1fffff, 0xfffffff, 0x10000000};
for (size_t i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
ccder_tag tag = limits[i] & CCDER_TAGNUM_MASK;
size_t length = i + 1; // this length is too short
uint8_t *invalid_der = malloc(length);
if (invalid_der) {
uint8_t *der_start = invalid_der;
uint8_t *der_end = invalid_der + length;
uint8_t *new_der_end = ccder_encode_tag(tag, der_start, der_end);
is(new_der_end, NULL, "ccder_encode_tag");
free(invalid_der);
}
length = i + 2;
uint8_t *valid_der = malloc(length);
if (valid_der) {
uint8_t *der_start = valid_der;
uint8_t *der_end = valid_der + length;
uint8_t *new_der_end = ccder_encode_tag(tag, der_start, der_end);
isnt(new_der_end, NULL, "ccder_encode_tag");
// We decode the first octet length, and then n, depending on what tag length we're decoding
is(new_der_end, der_end - (i + 2), "ccder_encode_tag expected %p, got %p", der_end - (i + 2), new_der_end);
free(valid_der);
}
}
}
//================================ ccder_encode_len ============================
static int testEncodeLen(void)
{
uint8_t tmp[5];
// 1 byte
memset(tmp,0,sizeof(tmp));
const uint8_t expected_result1[5]={0};
is(ccder_encode_len(0,(const uint8_t*)&tmp[0],&tmp[1]),&tmp[0],"ccder_encode_len return value for 1byte length");
ok_memcmp_or_fail(tmp, expected_result1,sizeof(tmp),"ccder_encode_len output for 1byte length");
// 2 bytes
memset(tmp,0,sizeof(tmp));
const uint8_t expected_result2[5]={0x81,0x80};
is(ccder_encode_len(0x80,(const uint8_t*)&tmp[0],&tmp[2]),&tmp[0],"ccder_encode_len return value for 2byte length");
ok_memcmp_or_fail(tmp, expected_result2,sizeof(tmp),"ccder_encode_len output for 2byte length");
// 3 bytes
memset(tmp,0,sizeof(tmp));
const uint8_t expected_result3[5]={0x82,0xFF,0xFE};
is(ccder_encode_len(0xFFFE,(const uint8_t*)&tmp[0],&tmp[3]),&tmp[0],"ccder_encode_len return value for 3byte length");
ok_memcmp_or_fail(tmp, expected_result3,sizeof(tmp),"ccder_encode_len output for 3byte length");
// 4 bytes
memset(tmp,0,sizeof(tmp));
const uint8_t expected_result4[5]={0x83,0xFF,0xFE,0xFD};
is(ccder_encode_len(0xFFFEFD,(const uint8_t*)&tmp[0],&tmp[4]),&tmp[0],"ccder_encode_len return value for 4byte length");
ok_memcmp_or_fail(tmp, expected_result4,sizeof(tmp),"ccder_encode_len output for 4byte length");
// 5 bytes
memset(tmp,0,sizeof(tmp));
const uint8_t expected_result5[5]={0x84,0xFF,0xFE,0xFD,0xFC};
is(ccder_encode_len(0xFFFEFDFC,(const uint8_t*)&tmp[0],&tmp[5]),&tmp[0],"ccder_encode_len return value for 5byte length");
ok_memcmp_or_fail(tmp, expected_result5,sizeof(tmp),"ccder_encode_len output for 5byte length");
if (sizeof(size_t)>4) {
// 5 bytes
is(ccder_encode_len((size_t)1<<33,&tmp[0],NULL),NULL, "length bigger than UINT32_MAX not supported"); // Expect error
} else {
pass("On 32bit platforms, the length can't exceed UINT32_MAX");
}
return 0;
}
//====================== ccder_decode_len ===================================
static void testDecodeLen(void)
{
uint8_t one_der[] = {0x81}; // one additional octet, but missing
uint8_t *der_start = one_der;
uint8_t *der_end = one_der + sizeof(one_der);
size_t len = 0;
const uint8_t *new_der = ccder_decode_len(&len, der_start, der_end);
is(new_der, NULL, "ccder_decode_len");
uint8_t two_der[] = {0x82, 0x01}; // two additional octets, but missing
der_start = two_der;
der_end = two_der + sizeof(two_der);
new_der = ccder_decode_len(&len, der_start, der_end);
is(new_der, NULL, "ccder_decode_len");
uint8_t three_der[] = {0x83, 0x01, 0x02}; // three additional octets, but missing
der_start = three_der;
der_end = three_der + sizeof(three_der);
new_der = ccder_decode_len(&len, der_start, der_end);
is(new_der, NULL, "ccder_decode_len");
size_t length = 0x112233;
uint8_t *valid_three_der = malloc(length + 4);
if (valid_three_der) {
valid_three_der[0] = 0x83;
valid_three_der[1] = (uint8_t)(length >> 16);
valid_three_der[2] = (uint8_t)(length >> 8);
valid_three_der[3] = (uint8_t)(length >> 0);
der_start = valid_three_der;
der_end = valid_three_der + length + 4;
new_der = ccder_decode_len(&len, der_start, der_end);
isnt(new_der, NULL, "ccder_decode_len");
is(new_der, valid_three_der + 4, "ccder_decode_len");
free(valid_three_der);
}
// Note: we do not parse lengths with four or more octets
}
//================================ ccder_encode_body ============================
static void testEncodeBody()
{
uint8_t der[] = {0x00};
size_t length = sizeof(der) + 1; // invalid size
uint8_t *body = NULL;
uint8_t *new_der = ccder_encode_body(length, body, der, der + sizeof(der));
is(new_der, NULL, "ccder_encode_body");
}
static void testEncodeBodyNoCopy()
{
uint8_t der[] = {0x00};
size_t length = sizeof(der) + 1; // invalid size
uint8_t *new_der = ccder_encode_body_nocopy(length, der, der + sizeof(der));
is(new_der, NULL, "ccder_encode_body");
}
//====================== ccder_decode_uint_n ===================================
typedef struct der_decode_uint_n_struct {
char *der_str_buf;
cc_size n;
int err;
} der_decode_uint_n_t;
der_decode_uint_n_t test_der_decode_uint_n[]={
{"0200",0,1}, // Must have one byte content
{"020100",0,0},
{"020101",1,0},
{"02020080",1,0},
{"028109008000000000000001",ccn_nof_size(8),0},
{"0281110080000000000000000000000000000001",ccn_nof_size(16),0},
{"02020040",0,1}, // Too many padding zeroes
{"0203000080",1,1}, // Too many padding zeroes
{"02810A00000000000000000001",1,1}, // Too many padding zeroes
{"0281088000000000000001",0,1}, // Negative
};
static void testDecodeUInt_n()
{
for (size_t i=0;i<sizeof(test_der_decode_uint_n)/sizeof(test_der_decode_uint_n[0]);i++) {
cc_size n=0;
byteBuffer der_buf=hexStringToBytes(test_der_decode_uint_n[i].der_str_buf);
uint8_t *der_end=der_buf->bytes+der_buf->len;
if (!test_der_decode_uint_n[i].err) {
is(ccder_decode_uint_n(&n,
der_buf->bytes,
der_end),
der_end, "ccder_decode_uint_n return value");
is(n,test_der_decode_uint_n[i].n, "ccder_decode_uint_n expected output");
} else {
is(ccder_decode_uint_n(&n,
der_buf->bytes,
der_end),
NULL, "ccder_decode_uint_n return value");
}
free(der_buf);
}
}
//====================== ccder_decode_uint64 ===================================
typedef struct der_decode_uint64_struct {
char *der_str_buf;
uint64_t v;
int err;
} der_decode_uint64_t;
der_decode_uint64_t test_der_decode_uint64[]={
{"0200",0,1}, // Must have one byte content
{"020100",0,0},
{"020101",1,0},
{"02020080",0x80,0},
{"02084070605040302010",0x4070605040302010,0},
{"0209008070605040302010",0x8070605040302010,0},
{"0209018070605040302010",0x8070605040302010,1}, // Too big to be uint64_t
{"02020040",1,1}, // Too many padding zeroes
{"0203000080",1,1}, // Too many padding zeroes
{"0281088000000000000001",0,1}, // Negative
{"02810A00000000000000000001",1,1}, // Too many padding zeroes
{"0281110001000000000000000000000000000001",0,1}, // Too big to be uint64_t
};
static void testDecodeUInt64()
{
for (size_t i=0;i<sizeof(test_der_decode_uint64)/sizeof(test_der_decode_uint64[0]);i++) {
uint64_t computed_v=0;
uint64_t expected_v=0;
byteBuffer der_buf=hexStringToBytes(test_der_decode_uint64[i].der_str_buf);
uint8_t *der_end=der_buf->bytes+der_buf->len;
if (!test_der_decode_uint64[i].err) {
expected_v=test_der_decode_uint64[i].v;
is(ccder_decode_uint64(&computed_v,
der_buf->bytes,
der_end),
der_end, "ccder_decode_uint64 return value");
is(computed_v,expected_v, "ccder_decode_uint64 expected output");
}
else {
is(ccder_decode_uint64(&computed_v,
der_buf->bytes,
der_end),
NULL, "ccder_decode_uint64 return value");
}
free(der_buf);
}
}
static void testDecodeEmptyBitstring()
{
uint8_t malformed_der_buffer[] = { CCDER_BIT_STRING, 0x00 };
size_t malformed_der_buffer_len = sizeof(malformed_der_buffer);
uint8_t *der_ptr = malformed_der_buffer;
size_t der_ptr_len = malformed_der_buffer_len;
uint8_t string[10];
size_t string_len = 0;
const uint8_t *new_der_ptr = ccder_decode_bitstring((const uint8_t **)&string, &string_len,
(const uint8_t *)der_ptr, (const uint8_t *)(der_ptr + der_ptr_len));
isnt(new_der_ptr, NULL, "ccder_decode_bitstring");
is(string_len, (size_t)0, "ccder_decode_bitstring returned non-empty bit string for empty bitstring container");
}
static void testDecodeNullBitstring()
{
uint8_t *der_ptr = NULL;
size_t der_ptr_len = 0;
uint8_t string[10];
size_t string_len = 0;
const uint8_t *new_der_ptr = ccder_decode_bitstring((const uint8_t **)&string, &string_len,
(const uint8_t *)der_ptr, (const uint8_t *)(der_ptr + der_ptr_len));
is(new_der_ptr, NULL, "ccder_decode_bitstring");
}
static void testDecodeBitstring() {
testDecodeEmptyBitstring();
testDecodeNullBitstring();
}
static void testDecodeOID() {
uint8_t malformed_der_buffer[] = { CCDER_OBJECT_IDENTIFIER, 0x00 };
size_t malformed_der_buffer_len = sizeof(malformed_der_buffer);
uint8_t *der_ptr = malformed_der_buffer;
size_t der_ptr_len = malformed_der_buffer_len;
uint8_t string[10];
size_t string_len = 0;
const uint8_t *new_der_ptr = ccder_decode_oid((const uint8_t **)&string, (const uint8_t *)der_ptr,
(const uint8_t *)(der_ptr + der_ptr_len));
isnt(new_der_ptr, NULL, "ccder_decode_oid");
is(string_len, (size_t)0, "ccder_decode_oid returned non-empty OID for empty OID container");
// Invalidate the tag length -- 0x84 is an invalid tag length
malformed_der_buffer[1] = 0x84;
new_der_ptr = ccder_decode_oid((const uint8_t **)&string, (const uint8_t *)der_ptr,
(const uint8_t *)(der_ptr + der_ptr_len));
is(new_der_ptr, NULL, "ccder_decode_oid");
}
//====================== ccder_decode_uint ===================================
typedef struct der_decode_uint_struct {
char *der_str_buf;
cc_unit v[CCN192_N];
int err;
} der_decode_uint_t;
der_decode_uint_t test_der_decode_uint[]={
{"0200", {CCN192_C(ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff)},1}, // Must have one byte content
{"020100", {CCN192_C(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)},0},
{"02020080", {CCN192_C(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,80)},0},
{"02020040", {CCN192_C(ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff)},1}, // Too many padding zeroes
{"0203000001", {CCN192_C(ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff)},1}, // Too many padding zeroes
{"02810A00000000000000000001", {CCN192_C(ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff)},1}, // Too many padding zeroes
{"0281088000000000000001", {CCN192_C(ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff)},1}, // Negative
{"02811901000000000000000000000000000000000000000000000000",
{CCN192_C(ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff)},1}, // Too big
};
static void testDecodeUInt()
{
for (size_t i=0;i<sizeof(test_der_decode_uint)/sizeof(test_der_decode_uint[0]);i++) {
cc_unit computed_v[CCN192_N];
byteBuffer der_buf=hexStringToBytes(test_der_decode_uint[i].der_str_buf);
uint8_t *der_end=der_buf->bytes+der_buf->len;
memset(computed_v,0xAA,sizeof(computed_v)); // Fill with a different value to start with.
if (!test_der_decode_uint[i].err) {
cc_unit *expected_v=test_der_decode_uint[i].v;
is(ccder_decode_uint(CCN192_N,computed_v,
der_buf->bytes,
der_end),
der_end, "ccder_decode_uint return value");
ok_memcmp(computed_v,expected_v,sizeof(test_der_decode_uint[i].v), "ccder_decode_uint expected output");
}
else {
is(ccder_decode_uint(CCN192_N, computed_v,
der_buf->bytes,
der_end),
NULL, "ccder_decode_uint64 return value");
}
free(der_buf);
}
}
const uint8_t derbuf1[] = { 0x30, 0x01, 0xAA };
const uint8_t derbuf2[] = { 0x30, 0x01, 0xAA, 0xBB }; // Too much data, but still valid
const uint8_t derbuf3[] = { 0x30, 0x03, 0xAA }; // No enough data for len
const uint8_t derbuf4[] = { 0x30, 0x84, 0xAA }; // Invalid length
typedef struct der_decode_tl_struct {
const uint8_t *der;
size_t der_len;
size_t next_der_offset; // 0 is test is invalid
size_t end_der_offset; // 0 is test is invalid
const char *description;
} der_decode_tl_t;
der_decode_tl_t test_der_decode_tl[] = {
{&derbuf1[0],0,0,0,"Wrong der_end"},
{&derbuf1[0],1,0,0,"Wrong der_end"},
{&derbuf1[0],2,0,0,"Wrong der_end"},
{&derbuf1[0],sizeof(derbuf1),2,3,"valid test, exactly enough data"},
{&derbuf2[0],sizeof(derbuf2),2,3,"valid test, too much data"},
{&derbuf3[0],sizeof(derbuf3),0,0,"No enough data for length"},
{&derbuf4[0],sizeof(derbuf4),0,0,"Invalid length"},
};
static void testDecode_tl()
{
for (size_t i = 0; i < sizeof(test_der_decode_tl) / sizeof(test_der_decode_tl[0]); i++) {
const der_decode_tl_t test = test_der_decode_tl[i];
const uint8_t *der_end = test.der+test.der_len;
const uint8_t *der_body_end = NULL;
const uint8_t *expected_return = NULL; // for errors
const uint8_t *expected_body_end = test.der; // for errors
if (test.next_der_offset) {
expected_return = test.der + test.next_der_offset;
expected_body_end = test.der + test.end_der_offset;
}
is(ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &der_body_end,
test.der,der_end), expected_return,
"%zu: %s", i, test.description);
is(der_body_end, expected_body_end, "%zu: %s", i, test.description);
}
}
static void testDecodeTag()
{
// The second byte of this multi-byte tag does not have the top-three bits reserved.
uint8_t malformed_der_buffer[sizeof(ccder_tag)];
for (size_t i = 0; i < sizeof(ccder_tag); i++) {
malformed_der_buffer[i] = 0xFF;
}
size_t malformed_der_buffer_len = sizeof(malformed_der_buffer);
uint8_t *der_ptr = malformed_der_buffer;
size_t der_ptr_len = malformed_der_buffer_len;
ccder_tag tag;
const uint8_t *body = ccder_decode_tag(&tag, der_ptr, der_ptr + der_ptr_len);
is(body, NULL, "ccder_decode_tag");
for (size_t i = 0; i < sizeof(ccder_tag); i++) {
malformed_der_buffer[i] = 0x00;
}
malformed_der_buffer[0] = 0xFF;
body = ccder_decode_tag(&tag, der_ptr, der_ptr + der_ptr_len);
isnt(body, NULL, "ccder_decode_tag");
}
static void testSizeofTag()
{
unsigned long limits[] = {0x1e, 0x7f, 0x3fff, 0x1fffff, 0xfffffff, 0x10000000};
for (size_t i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
ccder_tag tag = limits[i] & CCDER_TAGNUM_MASK;
size_t size = ccder_sizeof_tag(tag);
is(size, i + 1, "ccder_sizeof_tag expected %zu, got %zu", i + 1, size);
}
}
ccder_sig_test_vector sig_test_vectors[] = {
#include "ccder_signature_strict_vectors.inc"
{.signature = NULL}
};
static void test_ccder_decode_seqii_strict() {
for (int i = 0; sig_test_vectors[i].signature != NULL; i++) {
const ccder_sig_test_vector tv = sig_test_vectors[i];
cc_size n = ccn_nof(tv.nbits);
byteBuffer sig = hexStringToBytes(tv.signature);
const uint8_t *sig_end = sig->bytes + sig->len;
cc_unit r[n], s[n];
const uint8_t *result = ccder_decode_seqii_strict(n, r, s, sig->bytes, sig_end);
is(result != NULL, tv.valid, "Strict signature decoding error on test vector %d, %s", i, tv.signature);
if (tv.valid && result) {
cc_unit rp[n], sp[n];
byteBuffer tv_r = hexStringToBytes(tv.r);
byteBuffer tv_s = hexStringToBytes(tv.s);
ccn_read_uint(n, rp, tv_r->len, tv_r->bytes);
ccn_read_uint(n, sp, tv_s->len, tv_s->bytes);
free(tv_r);
free(tv_s);
ok_ccn_cmp(n, r, rp, "Incorrect r value on test vector %d", i);
ok_ccn_cmp(n, s, sp, "Incorrect s value on test vector %d", i);
} else {
is(1, 1, "Dummy test1");
is(1, 1, "Dummy test2");
}
free(sig);
}
return;
}
//=============================== MAIN ccder ===================================
int ccder_tests(TM_UNUSED int argc, TM_UNUSED char *const *argv)
{
int ntests = 159;
ntests += 386 * 3; // test_ccder_decode_seqii_strict (# test_vectors x # tests)
plan_tests(ntests);
testDecode_tl();
testDecodeTag();
testSizeOfUInt64();
testSizeOf();
testEncodeLen();
testDecodeLen();
testDecodeUInt();
testDecodeUInt_n();
testDecodeUInt64();
testDecodeBitstring();
testDecodeOID();
testEncodeBody();
testEncodeBodyNoCopy();
testSizeofTag();
testEncodeTag();
test_ccder_decode_seqii_strict();
return 0;
}
#endif // entryPoint(ccder,"ccder")