void appendBitBuffer(struct EncodedData* result, const BitBuffer* data) { BitBuffer copy = *data; while (copy.num_bits >= sizeof(unsigned int) * 8) { encode_big_endian_integer(decode_integer(©, sizeof(unsigned int) * 8), sizeof(unsigned int) * 8, result); } if (copy.num_bits > 0) { encode_big_endian_integer(decode_integer(©, copy.num_bits), copy.num_bits, result); } }
int decode_EtypeList(const unsigned char *p, size_t len, EtypeList *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; if(len < reallen) return ASN1_OVERRUN; len = reallen; { size_t origlen = len; int oldret = ret; ret = 0; (data)->len = 0; (data)->val = NULL; while(ret < origlen) { (data)->len++; (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len); e = decode_integer(p, len, &(data)->val[(data)->len-1], &l); FORW; len = origlen - ret; } ret += oldret; } if(size) *size = ret; return 0; fail: free_EtypeList(data); return e; }
static Octstr *radius_type_convert(int type, Octstr *value) { Octstr *ret = NULL; int i; switch (type) { case t_int: ret = octstr_format("%ld", decode_integer(value, 0, 4)); break; case t_string: ret = octstr_format("%s", octstr_get_cstr(value)); break; case t_ipaddr: ret = octstr_create(""); for (i = 0; i < 4; i++) { int c = octstr_get_char(value, i); Octstr *b = octstr_format("%d", c); octstr_append(ret, b); if (i < 3) octstr_append_cstr(ret, "."); octstr_destroy(b); } break; default: panic(0, "RADIUS: Attribute type %d does not exist.", type); break; } return ret; }
RADIUS_PDU *radius_pdu_unpack(Octstr *data_without_len) { RADIUS_PDU *pdu; int type, ident; long len, pos; ParseContext *context; Octstr *authenticator; len = octstr_len(data_without_len); if (len < 20) { error(0, "RADIUS: PDU was too short (%ld bytes).", octstr_len(data_without_len)); return NULL; } context = parse_context_create(data_without_len); type = parse_get_char(context); ident = parse_get_char(context); pdu = radius_pdu_create(type, NULL); if (pdu == NULL) return NULL; len = decode_integer(data_without_len, 2, 2) - 19; parse_skip(context, 2); debug("radius", 0, "RADIUS: Attributes len is %ld", len); authenticator = parse_get_octets(context, 16); octstr_dump_short(authenticator, 0, "RADIUS: Authenticator (md5) is:"); /* skipping back to context start for macro magic */ parse_context_destroy(context); context = parse_context_create(data_without_len); switch (type) { #define INTEGER(name, octets) \ pos = octstr_len(data_without_len) - parse_octets_left(context); \ p->name = decode_integer(data_without_len, pos, octets); \ parse_skip(context, octets); #define OCTETS(name, field_giving_octets) \ p->name = parse_get_octets(context, field_giving_octets); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields; \ radius_attr_unpack(&context, &pdu); } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while unpacking."); } parse_context_destroy(context); octstr_destroy(authenticator); return pdu; }
static void convertEndian(enum Encoding encoding, unsigned char output[], BitBuffer* data) { int numBytes = data->num_bits / 8; if (encoding == getMachineEncoding()) { int i; for (i = 0; i < numBytes; ++i) { output[i] = decode_integer(data, 8); } } else { int i; for (i = 0; i < numBytes; ++i) { output[numBytes - 1 - i] = decode_integer(data, 8); } } }
unsigned long long decode_long_integer(BitBuffer* buffer, int num_bits) { unsigned long long result = 0; while (num_bits > 0) { int size = num_bits > 32 ? 32 : num_bits; result <<= size; result |= decode_integer(buffer, size); num_bits -= size; } return result; }
unsigned int decode_little_endian_integer(BitBuffer* buffer, int num_bits) { // Little endian conversion only works for fields that are a multiple // of 8 bits. assert(num_bits % 8 == 0); int i; unsigned int result = 0; for (i = 0; i < num_bits / 8; ++i) { result |= decode_integer(buffer, 8) << (i * 8); } return result; }
int decode_AUTHDATA_TYPE(const unsigned char *p, size_t len, AUTHDATA_TYPE *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = decode_integer(p, len, (int*)data, &l); FORW; if(size) *size = ret; return 0; fail: free_AUTHDATA_TYPE(data); return e; }
int decode_ChopstixOrderKey(const unsigned char *p, size_t len, ChopstixOrderKey *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = decode_integer(p, len, data, &l); FORW; if(size) *size = ret; return 0; fail: free_ChopstixOrderKey(data); return e; }
unsigned int get_integer(const BitBuffer* buffer) { // We'll just create a copy of the buffer, and decode it's value. BitBuffer temp = *buffer; return decode_integer(&temp, temp.num_bits); }
int decode_EncryptedData(const unsigned char *p, size_t len, EncryptedData *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_ENCTYPE(p, len, &(data)->etype, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) (data)->kvno = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->kvno = malloc(sizeof(*(data)->kvno)); if((data)->kvno == NULL) return ENOMEM; e = decode_integer(p, len, (data)->kvno, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_octet_string(p, len, &(data)->cipher, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_EncryptedData(data); return e; }
int decode_ChopstixOrderItem(const unsigned char *p, size_t len, ChopstixOrderItem *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_CHOPSTIX_ITEMTYPE(p, len, &(data)->type, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_integer(p, len, &(data)->qty, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_ChopstixItemCode(p, len, &(data)->code, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 3, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_integer(p, len, &(data)->style, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 4, &l); if (e) (data)->special = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->special = malloc(sizeof(*(data)->special)); if((data)->special == NULL) return ENOMEM; e = decode_ChopstixSpecial(p, len, (data)->special, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 5, &l); if (e) (data)->subitems = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->subitems = malloc(sizeof(*(data)->subitems)); if((data)->subitems == NULL) return ENOMEM; e = decode_ChopstixSubItems(p, len, (data)->subitems, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_ChopstixOrderItem(data); return e; }
int decode_KRB_CRED(const unsigned char *p, size_t len, KRB_CRED *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_APPL, CONS, 22, &reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_integer(p, len, &(data)->pvno, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_MESSAGE_TYPE(p, len, &(data)->msg_type, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; if(len < reallen) return ASN1_OVERRUN; len = reallen; { size_t origlen = len; int oldret = ret; ret = 0; (&(data)->tickets)->len = 0; (&(data)->tickets)->val = NULL; while(ret < origlen) { (&(data)->tickets)->len++; (&(data)->tickets)->val = realloc((&(data)->tickets)->val, sizeof(*((&(data)->tickets)->val)) * (&(data)->tickets)->len); e = decode_Ticket(p, len, &(&(data)->tickets)->val[(&(data)->tickets)->len-1], &l); FORW; len = origlen - ret; } ret += oldret; } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 3, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_EncryptedData(p, len, &(data)->enc_part, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_KRB_CRED(data); return e; }
SMPP_PDU *smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len) { SMPP_PDU *pdu; unsigned long type; long len, pos; len = octstr_len(data_without_len); if (len < 4) { error(0, "SMPP: PDU was too short (%ld bytes).", octstr_len(data_without_len)); return NULL; } /* get the PDU type */ if ((type = decode_integer(data_without_len, 0, 4)) == -1) return NULL; /* create a coresponding representation structure */ pdu = smpp_pdu_create(type, 0); if (pdu == NULL) return NULL; pos = 0; switch (type) { #define OPTIONAL_BEGIN \ { /* Read optional parameters */ \ while (pos + 4 <= len) { \ struct smpp_tlv *tlv; \ unsigned long opt_tag, opt_len; \ opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \ debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag); \ opt_len = decode_integer(data_without_len, pos, 2); pos += 2; \ debug("sms.smpp", 0, "Optional parameter length read as %ld", opt_len); \ /* check configured TLVs */ \ tlv = smpp_tlv_get_by_tag(smsc_id, opt_tag); \ if (tlv != NULL) debug("sms.smpp", 0, "Found configured optional parameter `%s'", octstr_get_cstr(tlv->name)); #define TLV_INTEGER(mname, octets) \ if (SMPP_##mname == opt_tag) { \ /* check length */ \ if (opt_len > octets) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #mname, opt_len); \ pos += opt_len; \ continue; \ } \ INTEGER(mname, opt_len); \ if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_format("%ld", p->mname)); \ } else #define TLV_NULTERMINATED(mname, max_len) \ if (SMPP_##mname == opt_tag) { \ /* check length */ \ if (opt_len > max_len || pos+opt_len > len) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #mname, opt_len); \ pos += opt_len; \ continue; \ } \ copy_until_nul(#mname, data_without_len, &pos, opt_len, &p->mname); \ if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \ } else #define TLV_OCTETS(mname, min_len, max_len) \ if (SMPP_##mname == opt_tag) { \ /* check length */ \ if (opt_len < min_len || opt_len > max_len || pos + opt_len > len) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \ #mname, opt_len, min_len, max_len); \ pos += opt_len; \ continue; \ } \ p->mname = octstr_copy(data_without_len, pos, opt_len); \ pos += opt_len; \ if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \ } else #define OPTIONAL_END \ { \ Octstr *val = NULL; \ if (tlv != NULL) { \ /* found configured tlv */ \ /* check length */ \ if (opt_len > tlv->length) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %ld) dropped.", \ octstr_get_cstr(tlv->name), opt_len, tlv->length); \ pos += opt_len; \ continue; \ } \ switch (tlv->type) { \ case SMPP_TLV_INTEGER: { \ long val_i; \ if ((val_i = decode_integer(data_without_len, pos, opt_len)) == -1) \ goto err; \ val = octstr_format("%ld", val_i); \ dict_put(p->tlv, tlv->name, val); \ pos += opt_len; \ break; \ } \ case SMPP_TLV_OCTETS: { \ val = octstr_copy(data_without_len, pos, opt_len); \ dict_put(p->tlv, tlv->name, val); \ pos += opt_len; \ break; \ } \ case SMPP_TLV_NULTERMINATED: { \ if (copy_until_nul(octstr_get_cstr(tlv->name), data_without_len, &pos, opt_len, &val) == 0) \ dict_put(p->tlv, tlv->name, val); \ break; \ } \ default: \ panic(0, "SMPP: Internal error, unknown configured TLV type %d.", tlv->type); \ break; \ } \ } else { \ val = octstr_copy(data_without_len, pos, opt_len); \ if (val) \ octstr_binary_to_hex(val, 0); \ else \ val = octstr_create(""); \ warning(0, "SMPP: Unknown TLV(0x%04lx,0x%04lx,%s) for PDU type (%s) received!", \ opt_tag, opt_len, octstr_get_cstr(val), pdu->type_name); \ octstr_destroy(val); \ pos += opt_len; \ } \ } \ } \ } #define INTEGER(name, octets) \ if ((p->name = decode_integer(data_without_len, pos, octets)) == -1) \ goto err; \ pos += octets; #define NULTERMINATED(name, max_octets) \ /* just warn about errors but not fail */ \ copy_until_nul(#name, data_without_len, &pos, max_octets, &p->name); #define OCTETS(name, field_giving_octets) \ p->name = octstr_copy(data_without_len, pos, \ p->field_giving_octets); \ if (p->field_giving_octets != (unsigned long) octstr_len(p->name)) { \ error(0, "smpp_pdu: error while unpacking '" #name "', " \ "len is %ld but should have been %ld, dropping.", \ octstr_len(p->name), p->field_giving_octets); \ goto err; \ } else { \ pos += p->field_giving_octets; \ } #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields } break; #include "smpp_pdu.def" default: error(0, "Unknown SMPP_PDU type 0x%08lx, internal error while unpacking.", type); break; } return pdu; err: smpp_pdu_destroy(pdu); octstr_dump(data_without_len, 0); return NULL; }
int decode_TransitedEncoding(const unsigned char *p, size_t len, TransitedEncoding *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_integer(p, len, &(data)->tr_type, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_octet_string(p, len, &(data)->contents, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_TransitedEncoding(data); return e; }
int decode_ChopstixMenuitem(const unsigned char *p, size_t len, ChopstixMenuitem *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_integer(p, len, &(data)->gen, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_ChopstixItemCode(p, len, &(data)->code, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_general_string(p, len, &(data)->name, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 4, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_integer(p, len, &(data)->price, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 5, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_ChopstixItemStyles(p, len, &(data)->styles, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 6, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_ChopstixItemExtras(p, len, &(data)->extras, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 7, &l); if (e) (data)->subitems = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->subitems = malloc(sizeof(*(data)->subitems)); if((data)->subitems == NULL) return ENOMEM; e = decode_ChopstixItemExtras(p, len, (data)->subitems, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 8, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = decode_ChopstixFlags(p, len, &(data)->flags, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_ChopstixMenuitem(data); return e; }
SMPP_PDU *smpp_pdu_unpack(Octstr *data_without_len) { SMPP_PDU *pdu; unsigned long type; long len, pos; len = octstr_len(data_without_len); if (len < 4) { error(0, "SMPP: PDU was too short (%ld bytes).", octstr_len(data_without_len)); return NULL; } /* get the PDU type */ if ((type = decode_integer(data_without_len, 0, 4)) == -1) return NULL; /* create a coresponding representation structure */ pdu = smpp_pdu_create(type, 0); if (pdu == NULL) return NULL; pos = 0; switch (type) { #define OPTIONAL_BEGIN \ { /* Read optional parameters */ \ while (pos + 4 <= len) { \ unsigned long opt_tag, opt_len; \ opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \ debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag); \ opt_len = decode_integer(data_without_len, pos, 2); pos += 2; \ debug("sms.smpp", 0, "Optional parameter length read as %ld", opt_len); #define TLV_INTEGER(name, octets) \ if (SMPP_##name == opt_tag) { \ /* check length */ \ if (opt_len > octets) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #name, opt_len); \ pos += opt_len; \ continue; \ } \ INTEGER(name, opt_len); \ } else #define TLV_NULTERMINATED(name, max_len) \ if (SMPP_##name == opt_tag) { \ /* check length */ \ if (opt_len > max_len || pos+opt_len > len) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #name, opt_len); \ pos += opt_len; \ continue; \ } \ NULTERMINATED(name, opt_len); \ } else #define TLV_OCTETS(name, min_len, max_len) \ if (SMPP_##name == opt_tag) { \ /* check length */ \ if (opt_len < min_len || opt_len > max_len || pos + opt_len > len) { \ error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \ #name, opt_len, min_len, max_len); \ pos += opt_len; \ continue; \ } \ p->name = octstr_copy(data_without_len, pos, opt_len); \ pos += opt_len; \ } else #define OPTIONAL_END \ { \ Octstr *val = octstr_copy(data_without_len, pos, opt_len); \ if (val) octstr_binary_to_hex(val, 0); \ else val = octstr_create(""); \ error(0, "SMPP: Unknown TLV(0x%04lx,0x%04lx,%s) for PDU type (%s) received!", \ opt_tag, opt_len, octstr_get_cstr(val), pdu->type_name); \ pos += opt_len; \ octstr_destroy(val); \ } \ } \ } #define INTEGER(name, octets) \ p->name = decode_integer(data_without_len, pos, octets); \ pos += octets; #define NULTERMINATED(name, max_octets) \ p->name = copy_until_nul(data_without_len, &pos, max_octets); #define OCTETS(name, field_giving_octets) \ p->name = octstr_copy(data_without_len, pos, \ p->field_giving_octets); \ if (p->field_giving_octets != (unsigned long) octstr_len(p->name)) { \ error(0, "smpp_pdu: error while unpacking 'short_message', " \ "len is %ld but should have been %ld, dropping.", \ octstr_len(p->name), p->field_giving_octets); \ return NULL; \ } else { \ pos += p->field_giving_octets; \ } #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields } break; #include "smpp_pdu.def" default: error(0, "Unknown SMPP_PDU type, internal error while unpacking."); } return pdu; }
int decode_EncKrbCredPart(const unsigned char *p, size_t len, EncKrbCredPart *data, size_t *size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length (p, len, ASN1_C_APPL, CONS, 29, &reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; { int dce_fix; if((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,&reallen, &l); FORW; if(len < reallen) return ASN1_OVERRUN; len = reallen; { size_t origlen = len; int oldret = ret; ret = 0; (&(data)->ticket_info)->len = 0; (&(data)->ticket_info)->val = NULL; while(ret < origlen) { (&(data)->ticket_info)->len++; (&(data)->ticket_info)->val = realloc((&(data)->ticket_info)->val, sizeof(*((&(data)->ticket_info)->val)) * (&(data)->ticket_info)->len); e = decode_KrbCredInfo(p, len, &(&(data)->ticket_info)->val[(&(data)->ticket_info)->len-1], &l); FORW; len = origlen - ret; } ret += oldret; } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) (data)->nonce = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->nonce = malloc(sizeof(*(data)->nonce)); if((data)->nonce == NULL) return ENOMEM; e = decode_integer(p, len, (data)->nonce, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) (data)->timestamp = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->timestamp = malloc(sizeof(*(data)->timestamp)); if((data)->timestamp == NULL) return ENOMEM; e = decode_KerberosTime(p, len, (data)->timestamp, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 3, &l); if (e) (data)->usec = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->usec = malloc(sizeof(*(data)->usec)); if((data)->usec == NULL) return ENOMEM; e = decode_integer(p, len, (data)->usec, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 4, &l); if (e) (data)->s_address = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->s_address = malloc(sizeof(*(data)->s_address)); if((data)->s_address == NULL) return ENOMEM; e = decode_HostAddress(p, len, (data)->s_address, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, 5, &l); if (e) (data)->r_address = NULL; else { p += l; len -= l; ret += l; e = der_get_length (p, len, &newlen, &l); FORW; { int dce_fix; oldlen = len; if((dce_fix = fix_dce(newlen, &len)) < 0)return ASN1_BAD_FORMAT; (data)->r_address = malloc(sizeof(*(data)->r_address)); if((data)->r_address == NULL) return ENOMEM; e = decode_HostAddress(p, len, (data)->r_address, &l); FORW; if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; }else len = oldlen - newlen; } } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(dce_fix){ e = der_match_tag_and_length (p, len, (Der_class)0, (Der_type)0, 0, &reallen, &l); FORW; } } if(size) *size = ret; return 0; fail: free_EncKrbCredPart(data); return e; }