/* * Copyright (c) 2017 Lev Walkin . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include #include #include /* for .bits_unused member */ asn_enc_rval_t OCTET_STRING_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, enum jer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const char * const h2c = "0123456789ABCDEF"; const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; asn_enc_rval_t er = { 0, 0, 0 }; char scratch[16 * 3 + 4]; char *p = scratch; uint8_t *buf; uint8_t *end; size_t i; if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED; er.encoded = 0; /* * Dump the contents of the buffer in hexadecimal. */ buf = st->buf; end = buf + st->size; for(i = 0; buf < end; buf++, i++) { if(!(i % 16) && (i || st->size > 16)) { ASN__CALLBACK(scratch, p-scratch); p = scratch; ASN__TEXT_INDENT(1, ilevel); } *p++ = h2c[(*buf >> 4) & 0x0F]; *p++ = h2c[*buf & 0x0F]; *p++ = 0x20; } if(p - scratch) { p--; /* Remove the tail space */ ASN__CALLBACK3("\"", 1, scratch, p-scratch, "\"", 1); /* Dump the rest */ if(st->size > 16) ASN__TEXT_INDENT(1, ilevel-1); } ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; } static const struct OCTET_STRING__jer_escape_table_s { const char *string; int size; } OCTET_STRING__jer_escape_table[] = { #define OSXET(s) { s, sizeof(s) - 1 } OSXET("\074\156\165\154\057\076"), /* */ OSXET("\074\163\157\150\057\076"), /* */ OSXET("\074\163\164\170\057\076"), /* */ OSXET("\074\145\164\170\057\076"), /* */ OSXET("\074\145\157\164\057\076"), /* */ OSXET("\074\145\156\161\057\076"), /* */ OSXET("\074\141\143\153\057\076"), /* */ OSXET("\074\142\145\154\057\076"), /* */ OSXET("\074\142\163\057\076"), /* */ OSXET("\011"), /* \t */ OSXET("\012"), /* \n */ OSXET("\074\166\164\057\076"), /* */ OSXET("\074\146\146\057\076"), /* */ OSXET("\015"), /* \r */ OSXET("\074\163\157\057\076"), /* */ OSXET("\074\163\151\057\076"), /* */ OSXET("\074\144\154\145\057\076"), /* */ OSXET("\074\144\143\061\057\076"), /* */ OSXET("\074\144\143\062\057\076"), /* */ OSXET("\074\144\143\063\057\076"), /* */ OSXET("\074\144\143\064\057\076"), /* */ OSXET("\074\156\141\153\057\076"), /* */ OSXET("\074\163\171\156\057\076"), /* */ OSXET("\074\145\164\142\057\076"), /* */ OSXET("\074\143\141\156\057\076"), /* */ OSXET("\074\145\155\057\076"), /* */ OSXET("\074\163\165\142\057\076"), /* */ OSXET("\074\145\163\143\057\076"), /* */ OSXET("\074\151\163\064\057\076"), /* */ OSXET("\074\151\163\063\057\076"), /* */ OSXET("\074\151\163\062\057\076"), /* */ OSXET("\074\151\163\061\057\076"), /* */ { 0, 0 }, /* " " */ { 0, 0 }, /* ! */ { 0, 0 }, /* \" */ { 0, 0 }, /* # */ { 0, 0 }, /* $ */ { 0, 0 }, /* % */ OSXET("\046\141\155\160\073"), /* & */ { 0, 0 }, /* ' */ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */ {0,0},{0,0},{0,0},{0,0}, /* 89:; */ OSXET("\046\154\164\073"), /* < */ { 0, 0 }, /* = */ OSXET("\046\147\164\073"), /* > */ }; asn_enc_rval_t OCTET_STRING_encode_jer_utf8(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, enum jer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; asn_enc_rval_t er = { 0, 0, 0 }; uint8_t *buf, *end; uint8_t *ss; /* Sequence start */ ssize_t encoded_len = 0; (void)ilevel; /* Unused argument */ (void)flags; /* Unused argument */ if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED; buf = st->buf; end = buf + st->size; for(ss = buf; buf < end; buf++) { unsigned int ch = *buf; int s_len; /* Special encoding sequence length */ /* * Escape certain characters: X.680/11.15 */ if(ch < sizeof(OCTET_STRING__jer_escape_table) / sizeof(OCTET_STRING__jer_escape_table[0]) && (s_len = OCTET_STRING__jer_escape_table[ch].size)) { if(((buf - ss) && cb(ss, buf - ss, app_key) < 0) || cb(OCTET_STRING__jer_escape_table[ch].string, s_len, app_key) < 0) ASN__ENCODE_FAILED; encoded_len += (buf - ss) + s_len; ss = buf + 1; } } encoded_len += (buf - ss); if((buf - ss) && cb(ss, buf - ss, app_key) < 0) ASN__ENCODE_FAILED; er.encoded = encoded_len; ASN__ENCODED_OK(er); }