@@ -523,6 +523,18 @@ int emv_tlv_get_info(
523523 info -> format = EMV_FORMAT_B ;
524524 return 0 ;
525525
526+ case EMV_TAG_9F0A_ASRPD :
527+ info -> tag_name = "Application Selection Registered Proprietary Data (ASRPD)" ;
528+ info -> tag_desc =
529+ "Proprietary data allowing for proprietary processing during "
530+ "application selection. Proprietary data is identified using "
531+ "Proprietary Data Identifiers that are managed by EMVCo and "
532+ "their usage by the Application Selection processing is "
533+ "according to their intended usage, as agreed by EMVCo during "
534+ "registration." ;
535+ info -> format = EMV_FORMAT_B ;
536+ return emv_asrpd_get_string_list (tlv -> value , tlv -> length , value_str , value_str_len );
537+
526538 case EMV_TAG_9F0D_ISSUER_ACTION_CODE_DEFAULT :
527539 info -> tag_name = "Issuer Action Code (IAC) - Default" ;
528540 info -> tag_desc =
@@ -2124,6 +2136,74 @@ int emv_aid_get_string(
21242136 return 0 ;
21252137}
21262138
2139+ int emv_asrpd_get_string_list (
2140+ const uint8_t * asrpd ,
2141+ size_t asrpd_len ,
2142+ char * str ,
2143+ size_t str_len
2144+ )
2145+ {
2146+ struct str_itr_t itr ;
2147+
2148+
2149+ if (!asrpd || !asrpd_len ) {
2150+ return -1 ;
2151+ }
2152+
2153+ if (!str || !str_len ) {
2154+ // Caller didn't want the value string
2155+ return 0 ;
2156+ }
2157+
2158+ if (asrpd_len < 3 ) {
2159+ // Application Selection Registered Proprietary Data (ASRPD) must
2160+ // contain at least one ID and a length
2161+ return 1 ;
2162+ }
2163+
2164+ emv_str_list_init (& itr , str , str_len );
2165+
2166+ // Application Selection Registered Proprietary Data (ASRPD)
2167+ // See EMV 4.4 Book 1, 12.5
2168+ // See https://www.emvco.com/registered-ids/
2169+ while (asrpd_len ) {
2170+ uint16_t asrpd_id ;
2171+ size_t asrpd_entry_len ;
2172+
2173+ if (asrpd_len < 3 ) {
2174+ // Incomplete ASRPD entry
2175+ return 2 ;
2176+ }
2177+
2178+ asrpd_id = (asrpd [0 ] << 8 ) + asrpd [1 ];
2179+ switch (asrpd_id ) {
2180+ case EMV_ASRPD_ECSG :
2181+ emv_str_list_add (& itr , "European Cards Stakeholders Group" );
2182+ break ;
2183+
2184+ case EMV_ASRPD_TCEA :
2185+ emv_str_list_add (& itr , "Technical Cooperation ep2 Association" );
2186+ break ;
2187+
2188+ default :
2189+ emv_str_list_add (& itr , "Unknown ASRPD identifier" );
2190+ }
2191+
2192+ // Validate entry length
2193+ asrpd_entry_len = 2 + 1 + asrpd [2 ];
2194+ if (asrpd_entry_len > asrpd_len ) {
2195+ // Invalid ASRPD length
2196+ return 3 ;
2197+ }
2198+
2199+ // Advance
2200+ asrpd += asrpd_entry_len ;
2201+ asrpd_len -= asrpd_entry_len ;
2202+ }
2203+
2204+ return 0 ;
2205+ }
2206+
21272207int emv_aip_get_string_list (
21282208 const uint8_t * aip ,
21292209 size_t aip_len ,
0 commit comments