Eric Betts 9 месяцев назад
Родитель
Сommit
de4db26ea5
9 измененных файлов с 182 добавлено и 51 удалено
  1. 2 7
      eMRTD.asn1
  2. 4 4
      lib/asn1/DG1.c
  3. 1 1
      lib/asn1/DG1.h
  4. 12 8
      lib/asn1/MRZ.c
  5. 3 2
      lib/asn1/MRZ.h
  6. 3 5
      lib/asn1/Makefile.am.libasncodec
  7. 95 0
      lib/asn1/VisibleString.c
  8. 36 0
      lib/asn1/VisibleString.h
  9. 26 24
      passy_reader.c

+ 2 - 7
eMRTD.asn1

@@ -1,15 +1,10 @@
 Passport DEFINITIONS ::=
 BEGIN
 
-MRZ ::= [APPLICATION 31] OCTET STRING
+MRZ ::= VisibleString
 
-Application1 ::= SET {
-  mrz MRZ
-}
-
--- ASN.1 definition for the MRZ
 DG1 ::= [APPLICATION 1] IMPLICIT SEQUENCE {
-  mrz MRZ
+  mdz [APPLICATION 31] IMPLICIT MRZ
 }
 
 END

+ 4 - 4
lib/asn1/DG1.c

@@ -8,14 +8,14 @@
 #include "DG1.h"
 
 static asn_TYPE_member_t asn_MBR_DG1_1[] = {
-	{ ATF_NOFLAGS, 0, offsetof(struct DG1, mrz),
+	{ ATF_NOFLAGS, 0, offsetof(struct DG1, mdz),
 		(ASN_TAG_CLASS_APPLICATION | (31 << 2)),
-		0,
+		-1,	/* IMPLICIT tag at current level */
 		&asn_DEF_MRZ,
 		0,
 		{ 0, 0, 0 },
 		0, 0, /* No default value */
-		"mrz"
+		"mdz"
 		},
 };
 static const ber_tlv_tag_t asn_DEF_DG1_tags_1[] = {
@@ -23,7 +23,7 @@ static const ber_tlv_tag_t asn_DEF_DG1_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static const asn_TYPE_tag2member_t asn_MAP_DG1_tag2el_1[] = {
-    { (ASN_TAG_CLASS_APPLICATION | (31 << 2)), 0, 0, 0 } /* mrz */
+    { (ASN_TAG_CLASS_APPLICATION | (31 << 2)), 0, 0, 0 } /* mdz */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_DG1_specs_1 = {
 	sizeof(struct DG1),

+ 1 - 1
lib/asn1/DG1.h

@@ -21,7 +21,7 @@ extern "C" {
 
 /* DG1 */
 typedef struct DG1 {
-	MRZ_t	 mrz;
+	MRZ_t	 mdz;
 	
 	/* Context for parsing across buffer boundaries */
 	asn_struct_ctx_t _asn_ctx;

+ 12 - 8
lib/asn1/MRZ.c

@@ -8,25 +8,29 @@
 #include "MRZ.h"
 
 /*
- * This type is implemented using OCTET_STRING,
+ * This type is implemented using VisibleString,
  * so here we adjust the DEF accordingly.
  */
+asn_per_constraints_t asn_PER_type_MRZ_constr_1 CC_NOTUSED = {
+	{ APC_CONSTRAINED,	 7,  7,  32,  126 }	/* (32..126) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
 static const ber_tlv_tag_t asn_DEF_MRZ_tags_1[] = {
-	(ASN_TAG_CLASS_APPLICATION | (31 << 2)),
-	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (26 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_MRZ = {
 	"MRZ",
 	"MRZ",
-	&asn_OP_OCTET_STRING,
+	&asn_OP_VisibleString,
 	asn_DEF_MRZ_tags_1,
 	sizeof(asn_DEF_MRZ_tags_1)
-		/sizeof(asn_DEF_MRZ_tags_1[0]), /* 2 */
+		/sizeof(asn_DEF_MRZ_tags_1[0]), /* 1 */
 	asn_DEF_MRZ_tags_1,	/* Same as above */
 	sizeof(asn_DEF_MRZ_tags_1)
-		/sizeof(asn_DEF_MRZ_tags_1[0]), /* 2 */
-	{ 0, 0, OCTET_STRING_constraint },
+		/sizeof(asn_DEF_MRZ_tags_1[0]), /* 1 */
+	{ 0, &asn_PER_type_MRZ_constr_1, VisibleString_constraint },
 	0, 0,	/* No members */
-	&asn_SPC_OCTET_STRING_specs	/* Additional specs */
+	0	/* No specifics */
 };
 

+ 3 - 2
lib/asn1/MRZ.h

@@ -12,16 +12,17 @@
 #include <asn_application.h>
 
 /* Including external dependencies */
-#include <OCTET_STRING.h>
+#include <VisibleString.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* MRZ */
-typedef OCTET_STRING_t	 MRZ_t;
+typedef VisibleString_t	 MRZ_t;
 
 /* Implementation */
+extern asn_per_constraints_t asn_PER_type_MRZ_constr_1;
 extern asn_TYPE_descriptor_t asn_DEF_MRZ;
 asn_struct_free_f MRZ_free;
 asn_struct_print_f MRZ_print;

+ 3 - 5
lib/asn1/Makefile.am.libasncodec

@@ -1,21 +1,20 @@
 ASN_MODULE_SRCS=	\
 	./lib/asn1/MRZ.c	\
-	./lib/asn1/Application1.c	\
 	./lib/asn1/DG1.c
 
 ASN_MODULE_HDRS=	\
 	./lib/asn1/MRZ.h	\
-	./lib/asn1/Application1.h	\
 	./lib/asn1/DG1.h
 
 ASN_MODULE_HDRS+=./lib/asn1/OPEN_TYPE.h
 ASN_MODULE_SRCS+=./lib/asn1/OPEN_TYPE.c
 ASN_MODULE_HDRS+=./lib/asn1/constr_CHOICE.h
+ASN_MODULE_HDRS+=./lib/asn1/VisibleString.h
+ASN_MODULE_SRCS+=./lib/asn1/VisibleString.c
+ASN_MODULE_HDRS+=./lib/asn1/OCTET_STRING.h
 ASN_MODULE_SRCS+=./lib/asn1/constr_CHOICE.c
 ASN_MODULE_HDRS+=./lib/asn1/constr_SEQUENCE.h
 ASN_MODULE_SRCS+=./lib/asn1/constr_SEQUENCE.c
-ASN_MODULE_HDRS+=./lib/asn1/constr_SET.h
-ASN_MODULE_SRCS+=./lib/asn1/constr_SET.c
 ASN_MODULE_HDRS+=./lib/asn1/asn_application.h
 ASN_MODULE_SRCS+=./lib/asn1/asn_application.c
 ASN_MODULE_HDRS+=./lib/asn1/asn_ioc.h
@@ -27,7 +26,6 @@ ASN_MODULE_HDRS+=./lib/asn1/asn_random_fill.h
 ASN_MODULE_SRCS+=./lib/asn1/asn_random_fill.c
 ASN_MODULE_HDRS+=./lib/asn1/asn_bit_data.h
 ASN_MODULE_SRCS+=./lib/asn1/asn_bit_data.c
-ASN_MODULE_HDRS+=./lib/asn1/OCTET_STRING.h
 ASN_MODULE_SRCS+=./lib/asn1/OCTET_STRING.c
 ASN_MODULE_HDRS+=./lib/asn1/BIT_STRING.h
 ASN_MODULE_SRCS+=./lib/asn1/BIT_STRING.c

+ 95 - 0
lib/asn1/VisibleString.c

@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2003, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <VisibleString.h>
+
+/*
+ * VisibleString basic type description.
+ */
+static const ber_tlv_tag_t asn_DEF_VisibleString_tags[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)),	/* [UNIVERSAL 26] IMPLICIT ...*/
+	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
+};
+static asn_per_constraints_t asn_DEF_VisibleString_constraints = {
+	{ APC_CONSTRAINED, 7, 7, 0x20, 0x7e },	/* Value */
+	{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },	/* Size */
+	0, 0
+};
+asn_TYPE_operation_t asn_OP_VisibleString = {
+	OCTET_STRING_free,
+	OCTET_STRING_print_utf8,   /* ASCII subset */
+	OCTET_STRING_compare,
+	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
+#ifdef	ASN_DISABLE_OER_SUPPORT
+	0,
+	0,
+#else
+	OCTET_STRING_decode_oer,
+	OCTET_STRING_encode_oer,
+#endif  /* ASN_DISABLE_OER_SUPPORT */
+#ifdef	ASN_DISABLE_PER_SUPPORT
+	0,
+	0,
+#else
+	OCTET_STRING_decode_uper,
+	OCTET_STRING_encode_uper,
+#endif	/* ASN_DISABLE_PER_SUPPORT */
+	OCTET_STRING_random_fill,
+	0	/* Use generic outmost tag fetcher */
+};
+asn_TYPE_descriptor_t asn_DEF_VisibleString = {
+	"VisibleString",
+	"VisibleString",
+	&asn_OP_VisibleString,
+	asn_DEF_VisibleString_tags,
+	sizeof(asn_DEF_VisibleString_tags)
+	  / sizeof(asn_DEF_VisibleString_tags[0]) - 1,
+	asn_DEF_VisibleString_tags,
+	sizeof(asn_DEF_VisibleString_tags)
+	  / sizeof(asn_DEF_VisibleString_tags[0]),
+	{ 0, &asn_DEF_VisibleString_constraints, VisibleString_constraint },
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+int
+VisibleString_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
+                         asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+    const VisibleString_t *st = (const VisibleString_t *)sptr;
+
+	if(st && st->buf) {
+		uint8_t *buf = st->buf;
+		uint8_t *end = buf + st->size;
+
+		/*
+		 * Check the alphabet of the VisibleString.
+		 * ISO646, ISOReg#6
+		 * The alphabet is a subset of ASCII between the space
+		 * and "~" (tilde).
+		 */
+		for(; buf < end; buf++) {
+			if(*buf < 0x20 || *buf > 0x7e) {
+				ASN__CTFAIL(app_key, td, sptr,
+					"%s: value byte %ld (%d) "
+					"not in VisibleString alphabet (%s:%d)",
+					td->name,
+					(long)((buf - st->buf) + 1),
+					*buf,
+					__FILE__, __LINE__);
+				return -1;
+			}
+		}
+	} else {
+		ASN__CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+
+	return 0;
+}

+ 36 - 0
lib/asn1/VisibleString.h

@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef	_VisibleString_H_
+#define	_VisibleString_H_
+
+#include <OCTET_STRING.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef OCTET_STRING_t VisibleString_t;  /* Implemented via OCTET STRING */
+
+extern asn_TYPE_descriptor_t asn_DEF_VisibleString;
+extern asn_TYPE_operation_t asn_OP_VisibleString;
+
+asn_constr_check_f VisibleString_constraint;
+
+#define VisibleString_free          OCTET_STRING_free
+#define VisibleString_print         OCTET_STRING_print
+#define VisibleString_compare       OCTET_STRING_compare
+#define VisibleString_constraint    VisibleString_constraint
+#define VisibleString_decode_ber    OCTET_STRING_decode_ber
+#define VisibleString_encode_der    OCTET_STRING_encode_der
+#define VisibleString_decode_xer    OCTET_STRING_decode_xer_hex
+#define VisibleString_encode_xer    OCTET_STRING_encode_xer
+#define VisibleString_decode_uper   OCTET_STRING_decode_uper
+#define VisibleString_encode_uper   OCTET_STRING_encode_uper
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _VisibleString_H_ */

+ 26 - 24
passy_reader.c

@@ -413,33 +413,35 @@ NfcCommand passy_reader_state_machine(Passy* passy, PassyReader* passy_reader) {
             } while(body_offset < body_size);
             passy_log_bitbuffer(TAG, "DG1", passy_reader->DG1);
 
-        DG1_t* dg1 = 0;
-        dg1 = calloc(1, sizeof *dg1);
-        assert(dg1);
-        asn_dec_rval_t rval = asn_decode(0, ATS_DER, &asn_DEF_DG1, (void**)&dg1, bit_buffer_get_data(passy_reader->DG1), bit_buffer_get_size_bytes(passy_reader->DG1));
-
-        if(rval.code == RC_OK) {
-            FURI_LOG_I(TAG, "ASN.1 decode success");
-
-            char payloadDebug[384] = {0};
-            memset(payloadDebug, 0, sizeof(payloadDebug));
-            (&asn_DEF_DG1)
-                ->op->print_struct(
-                    &asn_DEF_DG1, dg1, 1, print_struct_callback, payloadDebug);
-            if(strlen(payloadDebug) > 0) {
-                FURI_LOG_D(TAG, "DG1: %s", payloadDebug);
+            DG1_t* dg1 = 0;
+            dg1 = calloc(1, sizeof *dg1);
+            assert(dg1);
+            asn_dec_rval_t rval = asn_decode(
+                0,
+                ATS_DER,
+                &asn_DEF_DG1,
+                (void**)&dg1,
+                bit_buffer_get_data(passy_reader->DG1),
+                bit_buffer_get_size_bytes(passy_reader->DG1));
+
+            if(rval.code == RC_OK) {
+                FURI_LOG_I(TAG, "ASN.1 decode success");
+
+                char payloadDebug[384] = {0};
+                memset(payloadDebug, 0, sizeof(payloadDebug));
+                (&asn_DEF_DG1)
+                    ->op->print_struct(&asn_DEF_DG1, dg1, 1, print_struct_callback, payloadDebug);
+                if(strlen(payloadDebug) > 0) {
+                    FURI_LOG_D(TAG, "DG1: %s", payloadDebug);
+                } else {
+                    FURI_LOG_D(TAG, "Received empty Payload");
+                }
             } else {
-                FURI_LOG_D(TAG, "Received empty Payload");
+                FURI_LOG_E(TAG, "ASN.1 decode failed: %d.  %d consumed", rval.code, rval.consumed);
             }
-        } else {
-            FURI_LOG_E(TAG, "ASN.1 decode failed");
-        }
-
-        free(dg1);
-        dg1 = 0;
-
-
 
+            free(dg1);
+            dg1 = 0;
 
         } else if(passy->read_type == PassyReadDG2) {
             ret = passy_reader_select_file(passy_reader, 0x0102);