// =================================================================== // header file #define CRYPTX_ASN1_GETCLASS(flags) ((flag)>>1 & 0b11) #define CRYPTX_ASN1_ISCONSTRUCTED(flags) ((flags) & 1) typedef enum { ASN1_OK, ASN1_EOF, ASN1_INVALID_ARG, ASN1_LEN_OVERFLOW, ASN1_SPEC_MISMATCH } asn1_error_t; struct asn1_context { void *asn1_data_start; void *asn1_data_end; void *asn1_this; void *asn1_next; }; asn1_error_t cryptx_asn1_start(struct asn1_context *ctx, void *asn1_data, size_t len); asn1_error_t cryptx_asn1_decode(struct asn1_context *ctx, uint8_t **element, size_t *element_len, uint8_t *tag, uint8_t *flags); asn1_error_t cryptx_asn1_next(struct asn1_context *ctx); // =================================================================== // demo code int main(void) { struct asn1_context asn1_state; asn1_error_t err; uint8_t *ptr; size_t elem_len; uint8_t tag; uint8_t flags; sprintf(CEMU_CONSOLE, "\n\n----------------------------------\nENCODEX ASN.1 Decoder Demo\n"); err = cryptx_asn1_start(&asn1_state, asn1_demo, sizeof asn1_demo); sprintf(CEMU_CONSOLE, "\nASN.1 parser init complete. Exit code %u.\n", err); if(err != ASN1_OK) return 1; while(err != ASN1_EOF){ err = cryptx_asn1_decode(&asn1_state, &ptr, &elem_len, &tag, &flags); if(err) sprintf(CEMU_CONSOLE, "Decoder error %u\n", err); else sprintf(CEMU_CONSOLE, "Object Data, Tag Id: %u, Flags: %u, Size: %u, Addr: %p\n", tag, flags, elem_len, ptr); if(!CRYPTX_ASN1_ISCONSTRUCTED(flags)){ err = cryptx_asn1_next(&asn1_state); } } return 0; } // =================================================================== // output ASN.1 parser init complete. Exit code 0. Object Data, Tag Id: 16, Flags: 1, Size: 159, Addr: d1ab80 Object Data, Tag Id: 16, Flags: 1, Size: 13, Addr: d1ab82 Object Data, Tag Id: 6, Flags: 0, Size: 9, Addr: d1ab84 Object Data, Tag Id: 5, Flags: 0, Size: 0, Addr: d1ab8f Object Data, Tag Id: 3, Flags: 0, Size: 141, Addr: d1ab92