diff --git a/lib/asn1/Key.c b/lib/asn1/Key.c new file mode 100644 index 0000000..fe4f22e --- /dev/null +++ b/lib/asn1/Key.c @@ -0,0 +1,60 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + * From ASN.1 module "Seader" + * found in "seader.asn1" + * `asn1c -D ./lib/asn1 -no-gen-example -no-gen-OER -no-gen-PER -pdu=all` + */ + +#include "Key.h" + +asn_TYPE_member_t asn_MBR_Key_1[] = { + { ATF_NOFLAGS, 0, offsetof(struct Key, referenceId), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "referenceId" + }, + { ATF_NOFLAGS, 0, offsetof(struct Key, crypto), + (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), + 0, + &asn_DEF_OCTET_STRING, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "crypto" + }, +}; +static const ber_tlv_tag_t asn_DEF_Key_tags_1[] = { + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) +}; +static const asn_TYPE_tag2member_t asn_MAP_Key_tag2el_1[] = { + { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* crypto */ + { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 0, 0, 0 } /* referenceId */ +}; +asn_SEQUENCE_specifics_t asn_SPC_Key_specs_1 = { + sizeof(struct Key), + offsetof(struct Key, _asn_ctx), + asn_MAP_Key_tag2el_1, + 2, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + -1, /* First extension addition */ +}; +asn_TYPE_descriptor_t asn_DEF_Key = { + "Key", + "Key", + &asn_OP_SEQUENCE, + asn_DEF_Key_tags_1, + sizeof(asn_DEF_Key_tags_1) + /sizeof(asn_DEF_Key_tags_1[0]), /* 1 */ + asn_DEF_Key_tags_1, /* Same as above */ + sizeof(asn_DEF_Key_tags_1) + /sizeof(asn_DEF_Key_tags_1[0]), /* 1 */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_Key_1, + 2, /* Elements count */ + &asn_SPC_Key_specs_1 /* Additional specs */ +}; + diff --git a/lib/asn1/Key.h b/lib/asn1/Key.h new file mode 100644 index 0000000..00325cd --- /dev/null +++ b/lib/asn1/Key.h @@ -0,0 +1,41 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + * From ASN.1 module "Seader" + * found in "seader.asn1" + * `asn1c -D ./lib/asn1 -no-gen-example -no-gen-OER -no-gen-PER -pdu=all` + */ + +#ifndef _Key_H_ +#define _Key_H_ + + +#include + +/* Including external dependencies */ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Key */ +typedef struct Key { + OCTET_STRING_t referenceId; + OCTET_STRING_t crypto; + + /* Context for parsing across buffer boundaries */ + asn_struct_ctx_t _asn_ctx; +} Key_t; + +/* Implementation */ +extern asn_TYPE_descriptor_t asn_DEF_Key; +extern asn_SEQUENCE_specifics_t asn_SPC_Key_specs_1; +extern asn_TYPE_member_t asn_MBR_Key_1[2]; + +#ifdef __cplusplus +} +#endif + +#endif /* _Key_H_ */ +#include diff --git a/lib/asn1/PACS.c b/lib/asn1/PACS.c new file mode 100644 index 0000000..06e2823 --- /dev/null +++ b/lib/asn1/PACS.c @@ -0,0 +1,50 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + * From ASN.1 module "Seader" + * found in "seader.asn1" + * `asn1c -D ./lib/asn1 -no-gen-example -no-gen-OER -no-gen-PER -pdu=all` + */ + +#include "PACS.h" + +asn_TYPE_member_t asn_MBR_PACS_1[] = { + { ATF_NOFLAGS, 0, offsetof(struct PACS, payload), + (ASN_TAG_CLASS_CONTEXT | (5 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "payload" + }, +}; +static const ber_tlv_tag_t asn_DEF_PACS_tags_1[] = { + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) +}; +static const asn_TYPE_tag2member_t asn_MAP_PACS_tag2el_1[] = { + { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 0, 0, 0 } /* payload */ +}; +asn_SEQUENCE_specifics_t asn_SPC_PACS_specs_1 = { + sizeof(struct PACS), + offsetof(struct PACS, _asn_ctx), + asn_MAP_PACS_tag2el_1, + 1, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + -1, /* First extension addition */ +}; +asn_TYPE_descriptor_t asn_DEF_PACS = { + "PACS", + "PACS", + &asn_OP_SEQUENCE, + asn_DEF_PACS_tags_1, + sizeof(asn_DEF_PACS_tags_1) + /sizeof(asn_DEF_PACS_tags_1[0]), /* 1 */ + asn_DEF_PACS_tags_1, /* Same as above */ + sizeof(asn_DEF_PACS_tags_1) + /sizeof(asn_DEF_PACS_tags_1[0]), /* 1 */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_PACS_1, + 1, /* Elements count */ + &asn_SPC_PACS_specs_1 /* Additional specs */ +}; + diff --git a/lib/asn1/PACS.h b/lib/asn1/PACS.h new file mode 100644 index 0000000..c86cb67 --- /dev/null +++ b/lib/asn1/PACS.h @@ -0,0 +1,40 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + * From ASN.1 module "Seader" + * found in "seader.asn1" + * `asn1c -D ./lib/asn1 -no-gen-example -no-gen-OER -no-gen-PER -pdu=all` + */ + +#ifndef _PACS_H_ +#define _PACS_H_ + + +#include + +/* Including external dependencies */ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* PACS */ +typedef struct PACS { + OCTET_STRING_t payload; + + /* Context for parsing across buffer boundaries */ + asn_struct_ctx_t _asn_ctx; +} PACS_t; + +/* Implementation */ +extern asn_TYPE_descriptor_t asn_DEF_PACS; +extern asn_SEQUENCE_specifics_t asn_SPC_PACS_specs_1; +extern asn_TYPE_member_t asn_MBR_PACS_1[1]; + +#ifdef __cplusplus +} +#endif + +#endif /* _PACS_H_ */ +#include diff --git a/lib/asn1/SIO.c b/lib/asn1/SIO.c new file mode 100644 index 0000000..9335be4 --- /dev/null +++ b/lib/asn1/SIO.c @@ -0,0 +1,100 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + * From ASN.1 module "Seader" + * found in "seader.asn1" + * `asn1c -D ./lib/asn1 -no-gen-example -no-gen-OER -no-gen-PER -pdu=all` + */ + +#include "SIO.h" + +static asn_TYPE_member_t asn_MBR_SIO_1[] = { + { ATF_NOFLAGS, 0, offsetof(struct SIO, rid), + (ASN_TAG_CLASS_CONTEXT | (1 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "rid" + }, + { ATF_POINTER, 1, offsetof(struct SIO, unknown3), + (ASN_TAG_CLASS_CONTEXT | (3 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_OCTET_STRING, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "unknown3" + }, + { ATF_NOFLAGS, 0, offsetof(struct SIO, unknown5), + (ASN_TAG_CLASS_CONTEXT | (5 << 2)), + +1, /* EXPLICIT tag at current level */ + &asn_DEF_NULL, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "unknown5" + }, + { ATF_NOFLAGS, 0, offsetof(struct SIO, key), + (ASN_TAG_CLASS_CONTEXT | (6 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_Key, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "key" + }, + { ATF_NOFLAGS, 0, offsetof(struct SIO, pacs), + (ASN_TAG_CLASS_CONTEXT | (7 << 2)), + -1, /* IMPLICIT tag at current level */ + &asn_DEF_PACS, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "pacs" + }, + { ATF_NOFLAGS, 0, offsetof(struct SIO, unknown9), + (ASN_TAG_CLASS_CONTEXT | (9 << 2)), + +1, /* EXPLICIT tag at current level */ + &asn_DEF_NULL, + 0, + { 0, 0, 0 }, + 0, 0, /* No default value */ + "unknown9" + }, +}; +static const ber_tlv_tag_t asn_DEF_SIO_tags_1[] = { + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) +}; +static const asn_TYPE_tag2member_t asn_MAP_SIO_tag2el_1[] = { + { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 0, 0, 0 }, /* rid */ + { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 1, 0, 0 }, /* unknown3 */ + { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 2, 0, 0 }, /* unknown5 */ + { (ASN_TAG_CLASS_CONTEXT | (6 << 2)), 3, 0, 0 }, /* key */ + { (ASN_TAG_CLASS_CONTEXT | (7 << 2)), 4, 0, 0 }, /* pacs */ + { (ASN_TAG_CLASS_CONTEXT | (9 << 2)), 5, 0, 0 } /* unknown9 */ +}; +static asn_SEQUENCE_specifics_t asn_SPC_SIO_specs_1 = { + sizeof(struct SIO), + offsetof(struct SIO, _asn_ctx), + asn_MAP_SIO_tag2el_1, + 6, /* Count of tags in the map */ + 0, 0, 0, /* Optional elements (not needed) */ + -1, /* First extension addition */ +}; +asn_TYPE_descriptor_t asn_DEF_SIO = { + "SIO", + "SIO", + &asn_OP_SEQUENCE, + asn_DEF_SIO_tags_1, + sizeof(asn_DEF_SIO_tags_1) + /sizeof(asn_DEF_SIO_tags_1[0]), /* 1 */ + asn_DEF_SIO_tags_1, /* Same as above */ + sizeof(asn_DEF_SIO_tags_1) + /sizeof(asn_DEF_SIO_tags_1[0]), /* 1 */ + { 0, 0, SEQUENCE_constraint }, + asn_MBR_SIO_1, + 6, /* Elements count */ + &asn_SPC_SIO_specs_1 /* Additional specs */ +}; + diff --git a/lib/asn1/SIO.h b/lib/asn1/SIO.h new file mode 100644 index 0000000..6b9f034 --- /dev/null +++ b/lib/asn1/SIO.h @@ -0,0 +1,46 @@ +/* + * Generated by asn1c-0.9.29 (http://lionet.info/asn1c) + * From ASN.1 module "Seader" + * found in "seader.asn1" + * `asn1c -D ./lib/asn1 -no-gen-example -no-gen-OER -no-gen-PER -pdu=all` + */ + +#ifndef _SIO_H_ +#define _SIO_H_ + + +#include + +/* Including external dependencies */ +#include +#include +#include "Key.h" +#include "PACS.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* SIO */ +typedef struct SIO { + OCTET_STRING_t rid; + OCTET_STRING_t *unknown3 /* OPTIONAL */; + NULL_t unknown5; + Key_t key; + PACS_t pacs; + NULL_t unknown9; + + /* Context for parsing across buffer boundaries */ + asn_struct_ctx_t _asn_ctx; +} SIO_t; + +/* Implementation */ +extern asn_TYPE_descriptor_t asn_DEF_SIO; + +#ifdef __cplusplus +} +#endif + +#endif /* _SIO_H_ */ +#include diff --git a/sam_api.c b/sam_api.c index cf4cc60..25c603d 100644 --- a/sam_api.c +++ b/sam_api.c @@ -376,12 +376,14 @@ bool seader_unpack_pacs(Seader* seader, uint8_t* buf, size_t size) { asn_dec_rval_t rval = asn_decode(0, ATS_DER, &asn_DEF_PAC, (void**)&pac, buf, size); if(rval.code == RC_OK) { +#ifdef ASN1_DEBUG char pacDebug[384] = {0}; (&asn_DEF_PAC) ->op->print_struct(&asn_DEF_PAC, pac, 1, seader_print_struct_callback, pacDebug); if(strlen(pacDebug) > 0) { FURI_LOG_D(TAG, "Received pac: %s", pacDebug); } +#endif memset(display, 0, sizeof(display)); if(seader_credential->sio[0] == 0x30) { @@ -389,6 +391,34 @@ bool seader_unpack_pacs(Seader* seader, uint8_t* buf, size_t size) { snprintf(display + (i * 2), sizeof(display), "%02x", seader_credential->sio[i]); } FURI_LOG_D(TAG, "SIO %s", display); + +#ifdef ASN1_DEBUG + SIO_t* sio = 0; + sio = calloc(1, sizeof *sio); + assert(sio); + rval = asn_decode( + 0, + ATS_DER, + &asn_DEF_SIO, + (void**)&sio, + seader_credential->sio, + seader_credential->sio_len); + + if(rval.code == RC_OK) { + FURI_LOG_D(TAG, "Decoded SIO"); + char sioDebug[384] = {0}; + (&asn_DEF_SIO) + ->op->print_struct( + &asn_DEF_SIO, sio, 1, seader_print_struct_callback, sioDebug); + if(strlen(sioDebug) > 0) { + FURI_LOG_D(TAG, "SIO: %s", sioDebug); + } + } else { + FURI_LOG_W(TAG, "Failed to decode SIO %d consumed", rval.consumed); + } + + ASN_STRUCT_FREE(asn_DEF_SIO, sio); +#endif } if(pac->size <= sizeof(seader_credential->credential)) { diff --git a/sam_api.h b/sam_api.h index 50d4a4f..1692136 100644 --- a/sam_api.h +++ b/sam_api.h @@ -11,6 +11,7 @@ #include "protocol/rfal_picopass.h" #include +#include #define ExternalApplicationA 0x44 #define NFCInterface 0x14 diff --git a/seader.asn1 b/seader.asn1 index 668aaa4..b0948a2 100644 --- a/seader.asn1 +++ b/seader.asn1 @@ -88,4 +88,24 @@ SamVersion ::= SEQUENCE { type [2] IMPLICIT OCTET STRING } +-- Black Hate Asia 25: Dismantling-the-seos-protocol. + +Key ::= SEQUENCE { + referenceId [1] IMPLICIT OCTET STRING, + crypto OCTET STRING +} + +PACS ::= SEQUENCE { + payload [5] IMPLICIT OCTET STRING +} + +SIO ::= SEQUENCE { + rid [1] IMPLICIT OCTET STRING, + unknown3 [3] IMPLICIT OCTET STRING OPTIONAL, + unknown5 [5] NULL, + key [6] IMPLICIT Key, + pacs [7] IMPLICIT PACS, + unknown9 [9] NULL +} + END