+++ /dev/null
-/*
- * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_system.h>
-#include <asn_internal.h>
-
-#include <oer_support.h>
-
-/*
- * Fetch the length determinant (X.696 08/2015, #8.6) into *len_r.
- * RETURN VALUES:
- * 0: More data expected than bufptr contains.
- * -1: Fatal error deciphering length.
- * >0: Number of bytes used from bufptr.
- */
-ssize_t
-oer_fetch_length(const void *bufptr, size_t size, size_t *len_r) {
- uint8_t first_byte;
- size_t len_len; /* Length of the length determinant */
- const uint8_t *b;
- const uint8_t *bend;
- size_t len;
-
- if(size == 0) {
- *len_r = 0;
- return 0;
- }
-
- first_byte = *(const uint8_t *)bufptr;
- if((first_byte & 0x80) == 0) { /* Short form */
- *len_r = first_byte; /* 0..127 */
- return 1;
- }
-
- len_len = (first_byte & 0x7f);
- if((1 + len_len) > size) {
- *len_r = 0;
- return 0;
- }
-
- b = (const uint8_t *)bufptr + 1;
- bend = b + len_len;
-
- for(; b < bend && *b == 0; b++) {
- /* Skip the leading 0-bytes */
- }
-
- if((bend - b) > (ssize_t)sizeof(size_t)) {
- /* Length is not representable by the native size_t type */
- *len_r = 0;
- return -1;
- }
-
- for(len = 0; b < bend; b++) {
- len = (len << 8) + *b;
- }
-
- if(len > RSIZE_MAX) { /* A bit of C11 validation */
- *len_r = 0;
- return -1;
- }
-
- *len_r = len;
- assert(len_len + 1 == (size_t)(bend - (const uint8_t *)bufptr));
- return len_len + 1;
-}
-
-
-/*
- * Serialize OER length. Returns the number of bytes serialized
- * or -1 if a given callback returned with negative result.
- */
-ssize_t
-oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb,
- void *app_key) {
- uint8_t scratch[1 + sizeof(length)];
- uint8_t *sp = scratch;
- int littleEndian = 1; /* Run-time detection */
- const uint8_t *pstart;
- const uint8_t *pend;
- const uint8_t *p;
- int add;
-
- if(length <= 127) {
- uint8_t b = length;
- if(cb(&b, 1, app_key) < 0) {
- return -1;
- }
- return 1;
- }
-
- if(*(char *)&littleEndian) {
- pstart = (const uint8_t *)&length + sizeof(length) - 1;
- pend = (const uint8_t *)&length;
- add = -1;
- } else {
- pstart = (const uint8_t *)&length;
- pend = pstart + sizeof(length);
- add = 1;
- }
-
- for(p = pstart; p != pend; p += add) {
- /* Skip leading zeros. */
- if(*p) break;
- }
-
- for(sp = scratch + 1; ; p += add) {
- *sp++ = *p;
- if(p == pend) break;
- }
- assert((sp - scratch) - 1 <= 0x7f);
- scratch[0] = 0x80 + ((sp - scratch) - 1);
-
- if(cb(scratch, sp - scratch, app_key) < 0) {
- return -1;
- }
-
- return sp - scratch;
-}
-