Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct asn1_specification {
- uint8_t len;
- uint8_t elem[1];
- };
- asn1_error_t asn1_decode(uint8_t *asn1_data, size_t asn1_len, asn1_obj_t *objs, size_t *objs_ret, struct asn1_specification *spec){
- uint8_t *asn1_current = asn1_data; // set current to start of data to decode
- uint8_t *asn1_end = asn1_current + asn1_len;
- if(*asn1_current == 0) asn1_current++;
- size_t i;
- for(i = 0; asn1_current < asn1_end; i++){ // loop until iter count hit. Break manually if done.
- asn1_obj_t *node_o = &objs[i];
- uint8_t spec_tag_form = (spec == NULL) ? 0 : spec->elem[i];
- uint8_t tag = *asn1_current++;
- //node_o->tag = (*asn1_current++) & 0b11111; // get numeric tag id
- uint8_t byte_2nd = *asn1_current++; // get byte 2. Can be size or can be size of size
- node_o->len = 0;
- if((byte_2nd>>7) & 1){ // if bit 7 of byte is set, this is a size word length
- uint8_t size_len = byte_2nd & 0x7f;
- if(size_len > 3) return ASN1_ARCH_BAD_LEN; // due to device limits, seq len limited to u24.
- rmemcpy((uint8_t*)&node_o->len, asn1_current, size_len);
- asn1_current += size_len;
- }
- else // else, this is a size byte
- node_o->len = byte_2nd;
- // pull out tag with associated flags
- node_o->tag = tag & 0b11111;
- node_o->f_constr = (tag>>5 & 1);
- node_o->f_class = (tag>>6 & 0b11);
- // retrieve data addr and length
- node_o->data = asn1_current;
- asn1_current += node_o->len;
- // if the constructed flag is set, this element may contain other encoded types
- if((node_o->f_constr) || (spec_tag_form == 1)){
- size_t node_interior_len;
- if(asn1_decode(node_o->data, node_o->len, node_o, &node_interior_len, NULL) == ASN1_OK){
- i--;
- i += node_interior_len;
- }
- }
- }
- *objs_ret = i;
- if (spec != NULL) {if(i != spec->len) return ASN1_SPEC_MISMATCH;}
- return ASN1_OK;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement