EMV Tag 91 - why the last 2 bytes are "0010"? - tags

EMV Tag 91
in the following example, why the last 2 bytes are "0010"?
example: TLV [910ABCF266A64FF136630010]
I need most help
Thanks!!!

The first 8 bytes are mandatory and contain the cryptogram.
The optional 1–8 bytes that follow are proprietary. Therefore, you need to know what payment application (and version) you are using: e.g., Mastercard M/Chip, American Express AEIPS, etc.
See 6.5.4 External Authenticate in EMV 4.3 Book 3

This Tag 0x91 Issuer Authentication Data belongs to MasterCard M/Chip specification.
8 bytes is Authorization Response Cryptogram (ARPC).
2 Bytes is ARPC Response Code (RC) according to M/Chip specification.
The RC value set by M/Chip card issuer and provide additional card commands to reset some counters on it.
The example Tag data parsed as followed:
# Cheef's parser.
# Copyright (C) 2008-2022 Aleksandr Shevelev. https://iso8583.info/
# lib : "/lib/MasterCard/M_Chip/4/" # M/Chip 4 Card Application Specifications
# tool : "TLVs"
# stat : 11 nodes, 0 lookup tables, 100.00% passed (1/1)
TLVs:#"910ABCF266A64FF136630010" # M/Chip 4, Tag + Length + Value (TLV) series
- x91:#"910ABCF266A64FF136630010" # M/Chip 4, Issuer Authentication Data
- tag: "91"
- len: "0A" # // 10
- val:#"BCF266A64FF136630010" # Issuer Authentication Data.
- ARPC: "BCF266A64FF13663" # Authorization Response Cryptogram
- RC:#"0010" # ARPC Response Code
- B01:#"00"
- n0: "0" # bits 8-5, RFU
- n1: "0" # bits 4-1, PIN try Counter
- B02: "10"
# ___1____ - bit 5, Approve online transaction
# ____0___ - bit 4, Do NOT update PIN Try Counter
# _____0__ - bit 3, Reset go online on next transaction
# ______00 - bits 2-1, Do not update offline counters

Related

STUN MESSAGE-INTEGRITY dummy definition

in RFC5389 MESSAGE-INTEGRITY calculation includes itself but with dummy content
dummy content is not defined
how can MESSAGE-INTEGRITY be verified without knowing dummy content value?
why would MESSAGE-INTEGRITY calculation include itself?
is't it faster to calculate MESSAGE-INTEGRITY and equally secure if it didn't include itself?
Since the MESSAGE-INTEGRITY attribute itself is not part of the hash, you can append whatever you want for the last 20 bytes. Just replace it with the hash of all the bytes leading up to the attribute itself.
The algorithm is basically this:
Let L be the original size of the STUN message byte stream. Should be the same as the value for MESSAGE LENGTH in the STUN message header.
Append a 4 byte header onto the STUN message followed by 20 null bytes
Adjust the LENGTH field of the STUN message to account for these 24 new bytes.
Compute the HMAC/SHA1 of the first L bytes of the message (all but the 24 bytes you just appended).
replace the 20 null bytes with the 20 bytes of the computed hash
And as discussed in comments, the bytes don't have to be null bytes, they can be anything - since they aren't included in the hash computation.
There's an implementation of MESSAGE-INTEGRITY for both short-term and long-term credentials on my Github: here and here

GitHub API OpenPGP key format

What is the format of the public_key field returned from GitHub REST API v3 for GPG Keys?
For example, the command curl -v -H "Accept: application/vnd.github.cryptographer-preview" https://api.github.com/users/DurandA/gpg_keys returns the following keys:
pub dsa2048/403094DF 2017-09-03 [SC] [expires: 2018-09-03]
uid [ultimate] Arnaud Durand <arnaud.durand#unifr.ch>
sub elg2048/A454F414 2017-09-03 [E] [expires: 2018-09-03]
According to the API doc:
The data returned in the public_key response field is not a GPG formatted key. When a user uploads a GPG key, it is parsed and the cryptographic public key is extracted and stored. This cryptographic key is what is returned by the APIs on this page. This key is not suitable to be used directly by programs like GPG.
Is it possible to use these keys from a CLI or programmatically?
The key returned is a bare (RSA, DSA, ...) key, which cannot be used by implementations of OpenPGP without "wrapping" it in a proper OpenPGP key packet again. I would not recommend to do so, why you should be able to construct the key packet again, you will have no chance in constructing binding signatures for subkeys and user IDs (this requires access to the private keys) and will not succeed and constructing something useful therefor.
The "OpenPGP model" of sharing keys in communities is fetching a current copy from the key server network (including all current certifications and revocations) instead of relying on possibly outdated versions in "third-party-locations" like GitHub. This is possible by fingerprints and key IDs that (more or less uniquely, see below) address specific keys -- do not search for mail addresses, everybody can create keys with arbitrary user IDs and keyservers do not perform any validation.
Instead, have another look at the APIs output, which returns keyid objects for all keys (some for subkeys):
[
{
"id": 3,
"primary_key_id": null,
"key_id": "3262EFF25BA0D270",
"public_key": "xsBNBFayYZ...",
"emails": [
{
"email": "mastahyeti#users.noreply.github.com",
"verified": true
}
],
[snip]
}
]
To use such a key ID, run gpg --recv-keys <key-id>. And drop GitHub a note to follow best practices and include the full fingerprint:
These 64-bit hex values (3262EFF25BA0D270 in this example) are long key IDs. While any programmatic references to keys should always include the key's fingerprint, not abbreviated key IDs, at least they do not provide short key IDs that heavily suffer under collision attacks.
As of writing, contents in public_key fields are base64-encoded OpenPGP packets, which are defined in RFC 4880. gpgpdump is useful to inspect them. For example,
$ curl -s https://api.github.com/users/DurandA/gpg_keys | jq -r '.[0].public_key' | base64 -d | ./gpgpdump
Public-Key Packet (tag 6) (814 bytes)
Version: 4 (current)
Public key creation time: 2017-09-04T06:53:50+08:00
59 ac 87 fe
Public-key Algorithm: DSA (Digital Signature Algorithm) (pub 17)
DSA p (2048 bits)
DSA q (q is a prime divisor of p-1) (256 bits)
DSA g (2046 bits)
DSA y (= g^x mod p where x is secret) (2047 bits)
As an OpenPGP key is composed of a series of OpenPGP packets, it is theoretically possible to reconstruct a key for verifying stuffs. To achieve that, an extra user ID packet and a GnuPG patch are needed. The following Python 3 script can be used to generate a user ID packet:
TAG_UID = 13
uid = 'foo#example.com'
# RFC 4880, Sec 4.2.1. Old Format Packet Lengths
header = bytes([0x80 | (TAG_UID << 2), len(uid)])
packet = header + uid.encode('ascii')
sys.stdout.buffer.write(packet)
And the following GnuPG patch forces verification even if there are no signatures.
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 4c172d692..eb4653535 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
## -177,7 +177,7 ## check_signature2 (ctrl_t ctrl,
gnupg_compliance_option_string (opt.compliance));
rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
}
- else if (!pk->flags.valid)
+ else if (0)
{
/* You cannot have a good sig from an invalid key. */
rc = gpg_error (GPG_ERR_BAD_PUBKEY);
Anyway, as there are no self-signatures, the verification result should not trusted.

Zookeeper communication protocol

I need to debug the data being exchanged between my kafka consumer and zookeeper using tcpdump. I went through the zookeeper documentation but could not find any write up about the zookeeper communication protocol i.e I get the following data dump using wireshark after removing headers. How do I interpret the data part?
Frame 1: 78 bytes on wire (624 bits), 78 bytes captured (624 bits)
Ethernet II, Src: 22:00:0a:xx:xx:xx (22:00:xx:xx:xx:xx), Dst: fe:ff:xx:xx:xx:xx (fe:ff:ff:xx:xx:xx)
Internet Protocol Version 4, Src: 10.234.xxx.xxx, Dst: 10.231.xxx.xxx
Transmission Control Protocol, Src Port: 51720 (51720), Dst Port: 2181 (2181), Seq: 1, Ack: 1, Len: 12
Data (12 bytes)
Data: 00000008fffffffe0000000b
[Length: 12]
Sorry, but I'm not aware of any convenient documentation that describes the Apache ZooKeeper wire protocol in any great detail. Internally, our codebase is using a framework called Jute, which is based on code originally adapted from Apache Hadoop. The framework allows definition of structured records, generates code based on those definitions, and then provides serialization/deserialization routines called by the rest of the ZooKeeper code.
The Jute record definitions are visible here:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/zookeeper.jute
The Jute framework code for handling these record definitions is visible here:
https://github.com/apache/zookeeper/tree/release-3.4.9/src/java/main/org/apache/jute
I think the only option for a deep understanding of the wire protocol would be to dig into this code.
After digging through a few layers of raw socket handling code (which uses either NIO or Netty depending on configuration), the real work of deserializing the payload happens in ZooKeeperServer#processPacket(ServerCnxn, ByteBuffer):
https://github.com/apache/zookeeper/blob/release-3.4.9/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java#L941
This is where it deserializes a RequestHeader, which is a common header of metadata at the front of all of the protocol's messages. The definition of RequestHeader is shown here:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/zookeeper.jute#L88-L91
We can see it consists of 2 4-byte integer fields: a connection ID followed by the type of the message. The type values are defined in ZooDefs here:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/java/main/org/apache/zookeeper/ZooDefs.java#L28
Knowing all of this, let's go back to your packet capture and try to make sense of it:
Data: 00000008fffffffe0000000b
00000008 - payload length
fffffffe - connection ID
0000000b - op code ("ping")
At the front of each message (even before the RequestHeader), there is the length of the payload. Here we see a length of 8 bytes.
The next 4 bytes are the connection ID, fffffffe.
The final 4 bytes are the op code, 0000000b (or 11 in decimal). Reading ZooDefs, we can see that this is the "ping" operation. The "ping" operation is used for periodic heartbeats between client and server. There is no additional data required in the payload for the "ping" operation, so this is the end of this packet, and there is no additional data after it. For different operations, there would be additional data in the payload, representing the arguments to the operation.
I hope this helps.

Asterisk::AGI perl - check if SIP channel is online?

I'm writing asterisk agi script for 1.8 asterisk. Before dial, I want to check if desired SIP channel is available.
But I cant find a way to check if SIP channel is online using Asterisk::AGI
trying $AGI->channel_status('SIP/1001');
but it always returns -1
I was thinking to use AMI, but it doesn't work from AGI script (only in debug asterisk -vvvvc)
You can get result of function SIP_PEER or function CHANNEL
pro-sip*CLI> core show function SIPPEER
-= Info about function 'SIPPEER' =-
[Synopsis]
Gets SIP peer information.
[Description]
Not available
[Syntax]
SIPPEER(peername[,item])
[Arguments]
item
ip - (default) The ip address.
port - The port number.
mailbox - The configured mailbox.
context - The configured context.
expire - The epoch time of the next expire.
dynamic - Is it dynamic? (yes/no).
callerid_name - The configured Caller ID name.
callerid_num - The configured Caller ID number.
callgroup - The configured Callgroup.
pickupgroup - The configured Pickupgroup.
codecs - The configured codecs.
status - Status (if qualify=yes).
regexten - Registration extension.
limit - Call limit (call-limit).
busylevel - Configured call level for signalling busy.
curcalls - Current amount of calls. Only available if call-limit
is set.
language - Default language for peer.
accountcode - Account code for this peer.
useragent - Current user agent id for peer.
maxforwards - The value used for SIP loop prevention in outbound
requests
chanvar[name] - A channel variable configured with setvar for this
peer.
codec[x] - Preferred codec index number <x> (beginning with
zero).
[See Also]
Not available
pro-sip*CLI>
pro-sip*CLI> core show function CHANNEL
-= Info about function 'CHANNEL' =-
[Synopsis]
Gets/sets various pieces of information about the channel.
[Description]
Gets/sets various pieces of information about the channel, additional <item>
may be available from the channel driver; see its documentation for details.
Any <item> requested that is not available on the current channel will return
an empty string.
[Syntax]
CHANNEL(item)
[Arguments]
item
Standard items (provided by all channel technologies) are:
amaflags - R/W the Automatic Message Accounting (AMA) flags on the
channel. When read from a channel, the integer value will always be
returned. When written to a channel, both the string format or integer
value is accepted.
1 - 'OMIT'
2 - 'BILLING'
3 - 'DOCUMENTATION'
accountcode - R/W the channel's account code.
audioreadformat - R/O format currently being read.
audionativeformat - R/O format used natively for audio.
audiowriteformat - R/O format currently being written.
callgroup - R/W call groups for call pickup.
channeltype - R/O technology used for channel.
checkhangup - R/O Whether the channel is hanging up (1/0)
language - R/W language for sounds played.
musicclass - R/W class (from musiconhold.conf) for hold music.
name - The name of the channel
parkinglot - R/W parkinglot for parking.
rxgain - R/W set rxgain level on channel drivers that support it.
secure_bridge_signaling - Whether or not channels bridged to this
channel require secure signaling
secure_bridge_media - Whether or not channels bridged to this channel
require secure media
state - R/O state for channel
tonezone - R/W zone for indications played
transfercapability - R/W ISDN Transfer Capability, one of:
SPEECH
DIGITAL
RESTRICTED_DIGITAL
3K1AUDIO
DIGITAL_W_TONES
VIDEO
txgain - R/W set txgain level on channel drivers that support it.
videonativeformat - R/O format used natively for video
trace - R/W whether or not context tracing is enabled, only available
*if CHANNEL_TRACE is defined*.
*chan_sip* provides the following additional options:
peerip - R/O Get the IP address of the peer.
recvip - R/O Get the source IP address of the peer.
from - R/O Get the URI from the From: header.
uri - R/O Get the URI from the Contact: header.
useragent - R/O Get the useragent.
peername - R/O Get the name of the peer.
t38passthrough - R/O '1' if T38 is offered or enabled in this channel,
otherwise '0'
rtpqos - R/O Get QOS information about the RTP stream
This option takes two additional arguments:
Argument 1:
'audio' Get data about the audio stream
'video' Get data about the video stream
'text' Get data about the text stream
Argument 2:
'local_ssrc' Local SSRC (stream ID)
'local_lostpackets' Local lost packets
'local_jitter' Local calculated jitter
'local_maxjitter' Local calculated jitter (maximum)
'local_minjitter' Local calculated jitter (minimum)
'local_normdevjitter'Local calculated jitter (normal
deviation)
'local_stdevjitter' Local calculated jitter (standard
deviation)
'local_count' Number of received packets
'remote_ssrc' Remote SSRC (stream ID)
'remote_lostpackets'Remote lost packets
'remote_jitter' Remote reported jitter
'remote_maxjitter' Remote calculated jitter (maximum)
'remote_minjitter' Remote calculated jitter (minimum)
'remote_normdevjitter'Remote calculated jitter (normal
deviation)
'remote_stdevjitter'Remote calculated jitter (standard
deviation)
'remote_count' Number of transmitted packets
'rtt' Round trip time
'maxrtt' Round trip time (maximum)
'minrtt' Round trip time (minimum)
'normdevrtt' Round trip time (normal deviation)
'stdevrtt' Round trip time (standard deviation)
'all' All statistics (in a form suited to
logging, but not for parsing)
rtpdest - R/O Get remote RTP destination information.
This option takes one additional argument:
Argument 1:
'audio' Get audio destination
'video' Get video destination
'text' Get text destination
Defaults to 'audio' if unspecified.
rtpsource - R/O Get source RTP destination information.
This option takes one additional argument:
Argument 1:
'audio' Get audio destination
'video' Get video destination
'text' Get text destination
Defaults to 'audio' if unspecified.
*chan_iax2* provides the following additional options:
osptoken - R/O Get the peer's osptoken.
peerip - R/O Get the peer's ip address.
peername - R/O Get the peer's username.
secure_signaling - R/O Get the if the IAX channel is secured.
secure_media - R/O Get the if the IAX channel is secured.
*chan_dahdi* provides the following additional options:
dahdi_channel - R/O DAHDI channel related to this channel.
dahdi_span - R/O DAHDI span related to this channel.
dahdi_type - R/O DAHDI channel type, one of:
analog
mfc/r2
pri
pseudo
ss7
keypad_digits - R/O PRI Keypad digits that came in with the SETUP
message.
reversecharge - R/O PRI Reverse Charging Indication, one of:
-1 - None
1 - Reverse Charging Requested
no_media_path - R/O PRI Nonzero if the channel has no B channel.
The channel is either on hold or a call waiting call.
buffers - W/O Change the channel's buffer policy (for the current
call only)
This option takes two arguments:
Number of buffers,
Buffer policy being one of:
'full'
'immediate'
'half'
echocan_mode - W/O Change the configuration of the active echo
canceller on the channel (if any), for the current call only.
Possible values are:
'on' Normal mode (the echo canceller is actually reinitalized)
'off' Disabled
'fax' FAX/data mode (NLP disabled if possible, otherwise co
mpletely disabled)
'voice' Voice mode (returns from FAX mode, reverting the changes
that were made)
[See Also]
Not available
Based on answer of arheops this is the working AGI to test a SIP channel status:
$AGI->exec("EXEC Set(TESTVAR=\${SIPPEER(8880101,status)})");
my $testvar = $AGI->get_variable('TESTVAR');
$AGI->verbose("testvar $testvar");
Cli log:
AGI.agi: testvar OK (170 ms)
of course qualify=yes should be set for the peer or globally

How to accurately parse smtp message status code (DSN)?

RFC1893 claims that status codes will come in the format below you can read more here.
But our bounce management system is having a hard time parsing error status code from bounce messages. We are able to get the raw message, but depending on the email server the code will come in different places. Is there any rule on how to parse this type of messages to obtain better results. We are not looking for the 100% solution but at least 80%.
This document defines a new set of status codes to report mail system
conditions. These status codes are intended to be used for media and
language independent status reporting. They are not intended for
system specific diagnostics.
The syntax of the new status codes
is defined as:
status-code = class "." subject "." detail
class = "2"/"4"/"5"
subject = 1*3digit
detail = 1*3digit
White-space characters and comments
are NOT allowed within a status-
code. Each numeric sub-code within
the status-code MUST be expressed
without leading zero digits.
The quote above from the RFC tells one thing but then the text below from a leading tool on bounce management says something different, where I can get a good source of standard status codes:
Return Code Description
0 UNDETERMINED - (ie. Recipient Reply)
10 HARD BOUNCE - (ie. User Unknown)
20 SOFT BOUNCE - General
21 SOFT BOUNCE - Dns Failure
22 SOFT BOUNCE - Mailbox Full
23 SOFT BOUNCE - Message Too Large
30 BOUNCE - NO EMAIL ADDRESS. VERY RARE!
40 GENERAL BOUNCE
50 MAIL BLOCK - General
51 MAIL BLOCK - Known Spammer
52 MAIL BLOCK - Spam Detected
53 MAIL BLOCK - Attachment Detected
54 MAIL BLOCK - Relay Denied
60 AUTO REPLY - (ie. Out Of Office)
70 TRANSIENT BOUNCE
80 SUBSCRIBE Request
90 UNSUBSCRIBE/REMOVE Request
100 CHALLENGE-RESPONSE
I'm not sure that it's a full answer, but this algorithm for detecting bounces might be useful.