Skip to content

Commit

Permalink
Added der_put_int32() and der_put_uint32() tools
Browse files Browse the repository at this point in the history
  • Loading branch information
vanrein committed Nov 23, 2017
1 parent 270bcbc commit 1f7ab24
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 0 deletions.
20 changes: 20 additions & 0 deletions include/quick-der/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,26 @@ int der_get_int32 (dercursor cursor, int32_t *valp);
/* Unpack a single unsigned integer. See also der_get_int32(). */
int der_get_uint32 (dercursor cursor, uint32_t *valp);

/* Pack an Int32 or UInt32 and return the number of bytes.
*
* The buffer types der_buf_int32_t and der_buf_uint32_t can hold the size of
* the longest possible value, excluding header. The return value from the
* function indicates the actual number of bytes used. The buffer pointer
* and return value can be combined to hold another dercursor.
*
* These functions never fail. Note that a returned derlen of 0 is valid.
*
* For the curious: the reason that der_buf_uint32_t is 5 bytes while
* der_buf_int32_t is only 4 bytes is that DER represents the INTEGER
* type in 2's complement, using the most compact representation possible.
* Unsigned values >= 0x80000000 need an extra byte 0x00 prefixed to avoid
* being interpreted as negative values.
*/
typedef uint8_t der_buf_int32_t [4];
dercursor der_put_int32 (uint8_t *der_buf_int32, int32_t value);
typedef uint8_t der_buf_uint32_t [5];
dercursor der_put_uint32 (uint8_t *der_buf_uint32, uint32_t value);

/* Compare the values pointed to by cursors @p c1 and @p c2.
* Returns 0 if the (binary) values are equal, otherwise returns
* the difference between the first two differing bytes (similar
Expand Down
2 changes: 2 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ set(quickder_SRC
der_walk.c
der_get_int32.c
der_get_uint32.c
der_put_int32.c
der_put_uint32.c
der_cmp.c
)

Expand Down
36 changes: 36 additions & 0 deletions lib/der_put_int32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Data-packing function.
*
* From: Rick van Rein <[email protected]>
*/


#include <stdint.h>

#include <quick-der/api.h>


/*
* Pack an Int32 and return the number of bytes. Do not pack a header
* around it. The function returns the number of bytes taken, even 0 is valid.
*/
dercursor der_put_int32 (uint8_t *der_buf_int32, int32_t value) {
dercursor retval;
int shift = 24;
retval.derptr = der_buf_int32;
retval.derlen = 0;
while (shift >= 0) {
if ((retval.derlen == 0) && (shift > 0)) {
// Skip sign-extending initial bytes
uint32_t neutro = (value >> (shift - 1) ) & 0x000001ff;
if ((neutro == 0x000001ff) || (neutro == 0x00000000)) {
shift -= 8;
continue;
}
}
der_buf_int32 [retval.derlen] = (value >> shift) & 0xff;
retval.derlen++;
shift -= 8;
}
return retval;
}

28 changes: 28 additions & 0 deletions lib/der_put_uint32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Data-packing function.
*
* From: Rick van Rein <[email protected]>
*/


#include <stdint.h>

#include <quick-der/api.h>


/*
* Pack an UInt32 and return the number of bytes. Do not pack a header
* around it. The function returns the number of bytes taken, even 0 is valid.
*/
dercursor der_put_uint32 (uint8_t *der_buf_uint32, uint32_t value) {
dercursor retval;
int ofs = 0;
if (value & 0x80000000) {
*der_buf_uint32 = 0x00;
ofs = 1;
}
retval = der_put_int32 (der_buf_uint32 + ofs, (int32_t) value);
retval.derptr -= ofs;
retval.derlen += ofs;
return retval;
}

7 changes: 7 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ target_link_libraries(der_data.test
quickderStatic)
add_test (der_data.test
der_data.test)

add_executable (int_putget.test
int_putget.c)
target_link_libraries (int_putget.test
quickderStatic)
add_test (int_putget.test
int_putget.test)
75 changes: 75 additions & 0 deletions test/int_putget.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* der_putget.c -- Test der_put_[u]int32 followed by der_get[u]int32 for identity.
*
* From: Rick van Rein <[email protected]>
*/


#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#include <quick-der/api.h>


int unsigned_tests (void) {
uint32_t tests [] = {
0, 1, 255, 256, 32767, 32768, 65535, 65536,
0x7fffffff, 0x80000000, 0xc0000000, 0xf0000000, 0xffffffff
};
int numtests = sizeof (tests) / sizeof (tests [0]);
int ok = 1;
int i;
for (i=0; i<numtests; i++) {
der_buf_uint32_t buf;
uint32_t val;
dercursor crs = der_put_uint32 (buf, tests [i]);
int fit = (der_get_uint32 (crs, &val) == 0);
int match = (val == tests [i]);
ok = ok && fit && match;
if (fit != 0) {
fprintf (stderr, "Unsigned integer %ul took %d bytes %02x %02x... and does not fit in 32 bits anymore\n", tests [i], crs.derlen, crs.derptr [0], crs.derptr [1]);
} else if (match != 0) {
fprintf (stderr, "Unsigned integer %ul took %d bytes and came back as %ul\n", tests [i], crs.derlen, val);
}
}
return ok;
}


int signed_tests (void) {
int32_t tests [] = {
0, 1, 255, 256, 32767, 32768, 65535, 65536,
-1, -255, -256, -257, -32767, -32768, -32769,
0x7fffffff, 0x7fffffff,
-0x7fffffff, -0x80000000, -0x40000000
};
int numtests = sizeof (tests) / sizeof (tests [0]);
int ok = 1;
int i;
for (i=0; i<numtests; i++) {
der_buf_int32_t buf;
int32_t val;
dercursor crs = der_put_int32 (buf, tests [i]);
int fit = (der_get_int32 (crs, &val) == 0);
int match = (val == tests [i]);
ok = ok && fit && match;
if (fit != 0) {
fprintf (stderr, "Signed integer %l took %d bytes %02x %02x... and does not fit in 32 bits anymore\n", tests [i], crs.derlen, crs.derptr [0], crs.derptr [1]);
} else if (match != 0) {
fprintf (stderr, "Signed integer %l took %d bytes and came back as %l\n", tests [i], crs.derlen, val);
}
}
return ok;
}


int main (int argc, char *argv []) {

int ok = 1;

ok = ok && unsigned_tests ();
ok = ok && signed_tests ();

exit (ok? 0: 1);

}

0 comments on commit 1f7ab24

Please sign in to comment.