コード例 #1
0
            public bool setKeyB(string skey)
            {
                Logger.Trace("Setting Key B");
                CardBuffer bkey = new CardBuffer(skey.Trim());

                return(setKeyB(bkey.GetBytes()));
            }
コード例 #2
0
        /*
         * SCardControl
         * ------------
         */
        void BtnControlClick(object sender, EventArgs e)
        {
            RCtrlClear();

            DynamicByteProvider p;

            byte[] b;

            p = (DynamicByteProvider)hexBoxCCtrl.ByteProvider;

            b = new byte[p.Length];

            for (int i = 0; i < p.Length; i++)
            {
                b[i] = p.ReadByte(i);
            }

            CardBuffer cctrl = new CardBuffer(b);

            Settings.HistoryControl.Add(cctrl.AsString());
            hist_ctrl_idx = -1;

            CardBuffer rctrl = channel.Control(cctrl);

            if (rctrl == null)
            {
                ShowError();
            }
            else
            {
                ShowSuccess();

                b = rctrl.GetBytes();

                p = new DynamicByteProvider(b);

                hexBoxRCtrl.ByteProvider = p;

                if (b.Length > 0)
                {
                    eResultByte.Text = String.Format("{0}", 0 - (int)b[0]);

                    if (b[0] == 0)
                    {
                        eResultByteExplain.Text = "Success";
                    }
                    else
                    {
                        ushort sw = (ushort)(0x6F00 | b[0]);
                        eResultByteExplain.Text = SCARD.CardStatusWordsToString(sw);
                    }
                }

                hexBoxRCtrl.BackColor        = hexBoxCApdu.BackColor;
                eResultByte.BackColor        = eCardAtr.BackColor;
                eResultByteExplain.BackColor = eCardAtr.BackColor;
            }
        }
コード例 #3
0
        /// <summary>
        /// Save sector
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void BtnOkClick(object sender, EventArgs e)
        {
            byte[]     AccessBits;
            byte[]     SectorTrailer;
            byte[]     KeyA;
            byte[]     KeyB;
            CardBuffer cardbufA;
            CardBuffer cardbufB;

            if (!MemoryCardMifareClassic.Sector.isKeyValid(cbKeyA.Text))
            {
                MessageBox.Show(this, "Key A: please supply a valid 6-byte value, in hexadecimal (12 hex digits).", "Invalid entry", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.DialogResult = DialogResult.None;
                return;
            }

            if (!MemoryCardMifareClassic.Sector.isKeyValid(cbKeyB.Text))
            {
                MessageBox.Show(this, "Key B: please supply a valid 6-byte value, in hexadecimal (12 hex digits).", "Invalid entry", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.DialogResult = DialogResult.None;
                return;
            }

            AccessBits = computeSectorTrailer();
            if ((AccessBits == null) || (AccessBits.Length != 4))
            {
                MessageBox.Show(this, "Failed to compute the access bits.", "Internal error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.DialogResult = DialogResult.Cancel;
                return;
            }

            SectorTrailer = new byte[16];

            cardbufA = new CardBuffer(cbKeyA.Text);
            cardbufB = new CardBuffer(cbKeyB.Text);
            KeyA     = cardbufA.GetBytes();
            KeyB     = cardbufB.GetBytes();

            Array.ConstrainedCopy(KeyA, 0, SectorTrailer, 0, KeyA.Length);
            Array.ConstrainedCopy(AccessBits, 0, SectorTrailer, KeyA.Length, AccessBits.Length);
            Array.ConstrainedCopy(KeyB, 0, SectorTrailer, KeyA.Length + AccessBits.Length, KeyB.Length);

            // Save keyA and keyB
            Settings.RememberKeyA(cbKeyA.Text);
            Settings.RememberKeyB(cbKeyB.Text);

            if (!sector.setKeyA(KeyA) || !sector.setKeyB(KeyB))
            {
                MessageBox.Show(this, "Failed to define the new keys.", "Internal error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.DialogResult = DialogResult.Cancel;
                return;
            }
            this.DialogResult = DialogResult.OK;
        }
コード例 #4
0
            public bool setWritingKeyFromString(string key)
            {
                if (!isKeyValid(key))
                {
                    return(false);
                }
                CardBuffer bkey = new CardBuffer(key.Trim());

                writingKey = bkey.GetBytes();
                return(true);
            }
コード例 #5
0
ファイル: NfcTag.cs プロジェクト: elicec/springcard.pcsc.sdk
        private byte[] SerializeContent()
        {
            if ((Content == null) || (Content.Count == 0))
            {
                Trace.WriteLine("Nothing to serialize");
                return(null);
            }

            CardBuffer result = new CardBuffer();

            for (int i = 0; i < Content.Count; i++)
            {
                bool   is_begin = (i == 0) ? true : false;
                bool   is_end   = (i == (Content.Count - 1)) ? true : false;
                byte[] t        = Content[i].GetBytes(is_begin, is_end);

                result.Append(t);
            }

            return(result.GetBytes());
        }
コード例 #6
0
        protected override bool Read()
        {
            Trace.WriteLine("Reading the NFC Forum type 2 Tag");

            ushort page = 0;

            if (!Recognize(_channel, ref _formatted, ref _formattable, ref _locked))
            {
                return(false);
            }

            CardBuffer buffer = new CardBuffer();

            for (page = 0; page < 256; page += 4)
            {
                byte[] data = ReadBinary(_channel, page, READ_4_PAGES);

                if (data == null)
                {
                    break;
                }

                if (page > 0)
                {
                    bool same_as_header = true;
                    for (int i = 0; i < OFFSET_USER_DATA; i++)
                    {
                        if (data[i] != buffer.GetByte(i))
                        {
                            same_as_header = false;
                            break;
                        }
                    }
                    if (same_as_header)
                    {
                        break;
                    }
                }

                buffer.Append(data);
            }

            Trace.WriteLine("Read " + buffer.Length + "B of data from the Tag");

            _raw_data = buffer.GetBytes();

            _capacity = _raw_data.Length;
            if (_capacity <= OFFSET_USER_DATA)
            {
                _capacity = 0;
                return(false);
            }

            if (!_formatted)
            {
                /* Guess the capacity from the read area */
                if ((_capacity > 64) && !_formatted)
                {
                    /* Drop the 16 last bytes if they are not empty (locks on Mifare UltraLight C) */
                    bool locks_found = false;
                    for (long i = _capacity - 16; i < _capacity; i++)
                    {
                        if (_raw_data[i] != 0)
                        {
                            locks_found = true;
                            break;
                        }
                    }
                    if (locks_found)
                    {
                        Trace.WriteLine("Locks found at the end");
                        _capacity -= 16;
                    }
                }
                _capacity -= OFFSET_USER_DATA;
                Trace.WriteLine("The Tag is not formatted, capacity=" + _capacity + "B");
            }
            else
            {
                /* Read the capacity in the CC */
                _capacity = 8 * _raw_data[14];
                Trace.WriteLine("The Tag is formatted, capacity read from the CC=" + _capacity + "B");
            }

            /* Is the tag empty ? */
            _is_empty = true;
            for (long i = 0; i < _capacity; i++)
            {
                if (_raw_data[OFFSET_USER_DATA + i] != 0)
                {
                    _is_empty = false;
                    break;
                }
            }

            if (_is_empty)
            {
                Trace.WriteLine("The Tag is empty");
                return(true);
            }

            byte[] ndef_data = null;

            if (!ParseUserData(buffer.GetBytes(OFFSET_USER_DATA, -1), ref ndef_data))
            {
                Trace.WriteLine("The parsing of the Tag failed");
                return(false);
            }

            if (ndef_data == null)
            {
                Trace.WriteLine("The Tag doesn't contain a NDEF");
                _is_empty = true;
                return(true);
            }

            _is_empty = false;

            Ndef[] t = Ndef.Parse(ndef_data);
            if (t == null)
            {
                Trace.WriteLine("The NDEF is invalid or unsupported");
                return(false);
            }

            Trace.WriteLine(t.Length + " NDEF record(s) found in the Tag");

            /* This NDEF is the new content of the tag */
            Content.Clear();
            for (int i = 0; i < t.Length; i++)
            {
                Content.Add(t[i]);
            }

            return(true);
        }
コード例 #7
0
ファイル: MainForm.cs プロジェクト: Sryn/springcard.pcsc.sdk
        void MiATRRegistryClick(object sender, EventArgs e)
        {
            EXImageListViewItem item = (EXImageListViewItem)lvReaders.SelectedItems[0];

            if (!item.SubItems[4].Text.Equals(""))
            {
                IntPtr hContext    = IntPtr.Zero;
                uint   _last_error = SCARD.EstablishContext(SCARD.SCOPE_SYSTEM, IntPtr.Zero, IntPtr.Zero, ref hContext);
                if (_last_error != SCARD.S_SUCCESS)
                {
                    MessageBox.Show("Error: can't establish context");
                    return;
                }

                CardBuffer cardBufAtr = new CardBuffer(item.SubItems[4].Text);
                byte[]     atr        = cardBufAtr.GetBytes();

                byte[] dummy    = new byte[99];
                int    cchCards = -1;              /*	SCARD_AUTOALLOCATE */
                _last_error = SCardListCards(hContext,
                                             atr,
                                             null,
                                             0,
                                             null,
                                             ref cchCards);

                if (_last_error != SCARD.S_SUCCESS)
                {
                    MessageBox.Show("Error: can't list cards");
                    return;
                }

                if (cchCards <= 1)
                {
                    /* Card not found. We need to add it. */
                    string name = "NoMinidriver-" + item.SubItems[4].Text;
                    _last_error = SCardIntroduceCardType(hContext,
                                                         name,
                                                         null,
                                                         null,
                                                         0,
                                                         atr,
                                                         null,
                                                         (uint)atr.Length);

                    if (_last_error != SCARD.S_SUCCESS)
                    {
                        MessageBox.Show("Error: can't introduce card type");
                        return;
                    }

                    _last_error = SCardSetCardTypeProviderName(hContext,
                                                               name,
                                                               2, /*	SCARD_PROVIDER_CSP	*/
                                                               "$DisableSCPnP$");

                    if (_last_error != SCARD.S_SUCCESS)
                    {
                        MessageBox.Show("Error: can't set card type provider name");
                        return;
                    }
                    else
                    {
                        MessageBox.Show("This card will now be recognized by the system");
                    }
                }
                else
                {
                    MessageBox.Show("This card is already recognized by the system");
                }
            }
        }
コード例 #8
0
 public LLCP_PDU(CardBuffer Buffer)
 {
     _bytes = Buffer.GetBytes();
 }
コード例 #9
0
ファイル: Program.cs プロジェクト: Sryn/springcard.pcsc.sdk
        public static void Main(string[] args)
        {
            bool   p_erase        = false;
            bool   p_prepare      = false;
            bool   p_lock         = false;
            bool   p_batch        = false;
            bool   p_continue     = false;
            string p_key          = null;
            int    p_key_type     = 0;
            string p_set_key      = null;
            int    p_set_key_type = 0;
            string p_reader       = null;
            int    p_size         = 0;
            bool   p_list         = false;

            bool nfc_verbose = false;
            bool nfc_silent  = false;

            byte[] blank_buffer = new byte[32];

            byte[] key_buffer = new byte[24];
            int    key_length = 0;

            byte[] set_key_buffer = new byte[24];
            int    set_key_length = 0;

            int    rc;
            UInt32 ndef_size;
            UInt32 cc_size = 32;

            Getopt g = new Getopt("NfcToolDesfire", args, "epwz:k:t:s:r:bclvqh");

            int c;

            while ((c = g.getopt()) != -1)
            {
                switch (c)
                {
                case 'e': p_erase = true; break;

                case 'p': p_prepare = true; break;

                case 'w': p_lock = true; break;

                case 'z': p_size = Int32.Parse(g.Optarg);
                    break;

                case 'k': p_key = g.Optarg;
                    break;

                case 't': p_key_type = Int32.Parse(g.Optarg);
                    break;

                case 's': p_set_key = g.Optarg;
                    break;

                case 'n': p_set_key_type = Int32.Parse(g.Optarg);
                    break;

                case 'r': p_reader = g.Optarg;
                    break;

                case 'l': p_list = true; break;

                case 'b': p_batch = true; break;

                case 'c': p_continue = true; break;

                case 'v': nfc_verbose = true; break;

                case 'q': nfc_silent = true; break;

                case 'h': hello();
                    usage();
                    return;

                case '?': hello();
                    helpmsg("Incorrect parameter(s)", nfc_silent);
                    return;

                default: hello();
                    helpmsg("Invalid command line.", nfc_silent);
                    return;
                }
            }


            if (!nfc_silent)
            {
                hello();
            }

            if (p_list)
            {
                string reader_list = "";
                for (int i = 0; i < SCARD.Readers.Length - 1; i++)
                {
                    reader_list += "Reader " + i + "=" + SCARD.Readers[i] + "  -  ";
                }
                reader_list += "Reader " + (SCARD.Readers.Length - 1) + "=" + SCARD.Readers[SCARD.Readers.Length - 1];
                Console.WriteLine(reader_list);
                return;
            }

            /* Check the minimum mandatory parameters */
            if ((!p_erase) && (!p_prepare) && (!p_lock))
            {
                helpmsg("No mode specified, nothing to do!", nfc_silent);
                return;
            }

            if ((p_erase || p_prepare) && (p_lock))
            {
                helpmsg("Multiple modes specified, choose one!", nfc_silent);
                return;
            }

            /* Retrieve the key(s) */
            if (p_erase || p_prepare)
            {
                if (p_key == null)
                {
                    if (nfc_verbose)
                    {
                        Console.WriteLine("Key not specified, using default");
                    }

                    key_buffer = new byte[24];
                    for (int i = 0; i < key_buffer.Length; i++)
                    {
                        key_buffer[i] = 0;
                    }

                    key_length = 8;
                }
                else
                {
                    CardBuffer key = new CardBuffer(p_key);
                    key_buffer = new byte[24];
                    Array.ConstrainedCopy(key.GetBytes(), 0, key_buffer, 0, key.GetBytes().Length);
                    key_length = key.GetBytes().Length;
                }

                if ((key_length != 8) && (key_length != 16) && (key_length != 24))
                {
                    helpmsg("Key: invalid parameter", nfc_silent);
                    return;
                }

                if (key_length == 8)
                {
                    Array.ConstrainedCopy(key_buffer, 0, key_buffer, 8, 8);
                    Array.ConstrainedCopy(key_buffer, 0, key_buffer, 16, 8);
                }
                else
                if (key_length == 16)
                {
                    Array.ConstrainedCopy(key_buffer, 0, key_buffer, 16, 8);
                }

                if (p_key_type == 0)
                {
                    if (key_length == 8)
                    {
                        if (!nfc_silent)
                        {
                            Console.WriteLine("Type of key not specified, assuming DES");
                        }
                        p_key_type = KEY_DES_OR_3DES;
                    }
                    else
                    if (key_length == 16)
                    {
                        if (!nfc_silent)
                        {
                            Console.WriteLine("Type of key not specified, assuming TripleDES");
                        }
                        p_key_type = KEY_DES_OR_3DES;
                    }
                    else
                    if (key_length == 24)
                    {
                        if (!nfc_silent)
                        {
                            Console.WriteLine("Type of key not specified, assuming TripleDES with 3 keys");
                        }
                        p_key_type = KEY_DES_OR_3DES_ISO;
                    }
                    else
                    {
                        helpmsg("You must specify the type of the key!", nfc_silent);
                        return;
                    }
                }


                if (p_set_key != null)
                {
                    CardBuffer set_key = new CardBuffer(p_set_key);
                    set_key_buffer = new byte[24];
                    Array.ConstrainedCopy(set_key.GetBytes(), 0, set_key_buffer, 0, set_key.GetBytes().Length);
                    set_key_length = set_key.GetBytes().Length;


                    if ((set_key_length != 8) && (set_key_length != 16) && (set_key_length != 24))
                    {
                        helpmsg("New key: invalid parameter", nfc_silent);
                        return;
                    }

                    if (set_key_length == 8)
                    {
                        Array.ConstrainedCopy(set_key_buffer, 0, set_key_buffer, 8, 8);
                        Array.ConstrainedCopy(set_key_buffer, 0, set_key_buffer, 16, 8);
                    }
                    else
                    if (set_key_length == 16)
                    {
                        Array.ConstrainedCopy(set_key_buffer, 0, set_key_buffer, 16, 8);
                    }

                    if (p_set_key_type == 0)
                    {
                        if (set_key_length == 8)
                        {
                            if (!nfc_silent)
                            {
                                Console.WriteLine("Type of new key not specified, assuming DES");
                            }
                            p_set_key_type = KEY_DES_OR_3DES;
                        }
                        else
                        if (set_key_length == 16)
                        {
                            if (!nfc_silent)
                            {
                                Console.WriteLine("Type of new key not specified, assuming TripleDES");
                            }
                            p_set_key_type = KEY_DES_OR_3DES;
                        }
                        else
                        if (set_key_length == 24)
                        {
                            if (!nfc_silent)
                            {
                                Console.WriteLine("Type of new key not specified, assuming TripleDES with 3 keys");
                            }
                            p_set_key_type = KEY_DES_OR_3DES_ISO;
                        }
                        else
                        {
                            helpmsg("You must specify the type of the new key!", nfc_silent);
                            return;
                        }
                    }
                }
            }

            if (p_reader == null)
            {
                helpmsg("No Reader selected!", nfc_silent);
                return;
            }


            string ReaderName;

            /* Verify the reader */
            try
            {
                ReaderName = SCARD.Readers[Int32.Parse(p_reader)];
            }
            catch
            {
                Console.WriteLine("Reader not found!");
                return;
            }
            if (p_reader == null)
            {
                Console.WriteLine("Reader not found!");
                return;
            }

            if (!nfc_silent)
            {
                Console.WriteLine("Looking for Desfire EV1 card on reader " + ReaderName);
            }


batch_begin:

            /* Connect to the card */
            SCardChannel scard = new SCardChannel(ReaderName);

            if (scard == null)
            {
                Console.WriteLine("Failed to connect to the target card.");
                if (p_batch && p_continue)
                {
                    goto batch_begin;
                }
                goto failed;
            }

            if (!scard.Connect())
            {
                Console.WriteLine("Failed to connect to the target card.");
                if (p_batch && p_continue)
                {
                    goto batch_begin;
                }
                goto failed;
            }

            /* Open the Desfire DLL */
            rc = SCARD_DESFIRE.AttachLibrary(scard.hCard);
            if (rc != SCARD.S_SUCCESS)
            {
                Console.WriteLine("Failed to instantiate the PC/SC Desfire DLL.");
                goto failed;
            }

            rc = SCARD_DESFIRE.IsoWrapping(scard.hCard, DF_ISO_WRAPPING_CARD);
            if (rc != SCARD.S_SUCCESS)
            {
                Console.WriteLine("Failed to select the ISO 7816 wrapping mode.");
                goto failed;
            }

            byte[] version_info = new byte[30];

            rc = SCARD_DESFIRE.GetVersion(scard.hCard, version_info);
            if (rc != SCARD.S_SUCCESS)
            {
                Console.WriteLine("Desfire 'get version' command failed.");
                if (p_batch && p_continue)
                {
                    goto batch_end;
                }
                goto failed;
            }

            if (!nfc_silent)
            {
                Console.WriteLine("Found a Desfire card\n");
            }

            if (nfc_verbose)
            {
                Console.WriteLine("Hardware: Vendor=" + version_info[0]
                                  + ", Type=" + version_info[1]
                                  + ", SubType=" + version_info[2]
                                  + ", v" + version_info[3] + "." + version_info[4]);

                Console.WriteLine("Software: Vendor=" + version_info[7]
                                  + ", Type=" + version_info[8]
                                  + ", SubType=" + version_info[9]
                                  + ", v" + version_info[10] + "." + version_info[11]);
            }


            if ((version_info[0] != 0x04) || (version_info[7] != 0x04))
            {
                Console.WriteLine("Manufacturer is not NXP\n");
                if (p_batch && p_continue)
                {
                    goto batch_end;
                }
                goto failed;
            }

            if ((version_info[1] != 0x01) || (version_info[8] != 0x01))
            {
                Console.WriteLine("Type is not Desfire\n");
                if (p_batch && p_continue)
                {
                    goto batch_end;
                }
                goto failed;
            }

            if (version_info[10] < 1)
            {
                Console.WriteLine("Software version is below EV1\n");
                if (p_batch && p_continue)
                {
                    goto batch_end;
                }
                goto failed;
            }

            if (p_erase || p_prepare)
            {
                if (nfc_verbose)
                {
                    Console.WriteLine("Authenticating...");
                }

                switch (p_key_type)
                {
                case KEY_DES_OR_3DES: rc = SCARD_DESFIRE.Authenticate(scard.hCard, 0, key_buffer); break;

                case KEY_DES_OR_3DES_ISO: rc = SCARD_DESFIRE.AuthenticateIso24(scard.hCard, 0, key_buffer); break;

                case KEY_AES_ISO: rc = SCARD_DESFIRE.AuthenticateAes(scard.hCard, 0, key_buffer); break;

                default: rc = -1; break;
                }
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Authentication failed");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }
                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (set_key_length > 0)
                {
                    if (nfc_verbose)
                    {
                        Console.WriteLine("Setting the new key...");
                    }

                    if ((p_key_type == KEY_DES_OR_3DES) && (p_set_key_type == KEY_DES_OR_3DES))
                    {
                        rc = SCARD_DESFIRE.ChangeKey(scard.hCard, 0, set_key_buffer, null);
                    }
                    else
                    if ((p_key_type == KEY_DES_OR_3DES) && (p_set_key_type == KEY_DES_OR_3DES_ISO))
                    {
                        rc = SCARD_DESFIRE.AuthenticateIso24(scard.hCard, 0, key_buffer);
                        if (rc == SCARD.S_SUCCESS)
                        {
                            rc = SCARD_DESFIRE.ChangeKey24(scard.hCard, 0, set_key_buffer, null);
                        }
                    }
                    else
                    if ((p_key_type == KEY_DES_OR_3DES) && (p_set_key_type == KEY_AES_ISO))
                    {
                        rc = SCARD_DESFIRE.ChangeKeyAes(scard.hCard, DF_APPLSETTING2_AES | 0, 0, set_key_buffer, null);
                    }
                    else
                    if ((p_key_type == KEY_DES_OR_3DES_ISO) && (p_set_key_type == KEY_DES_OR_3DES))
                    {
                        rc = SCARD_DESFIRE.ChangeKeyAes(scard.hCard, DF_APPLSETTING2_AES | 0, 0, blank_buffer, null);
                        if (rc == SCARD.S_SUCCESS)
                        {
                            rc = SCARD_DESFIRE.AuthenticateAes(scard.hCard, 0, blank_buffer);
                        }
                        if (rc == SCARD.S_SUCCESS)
                        {
                            rc = SCARD_DESFIRE.ChangeKey(scard.hCard, 0, set_key_buffer, null);
                        }
                    }
                    else
                    if ((p_key_type == KEY_DES_OR_3DES_ISO) && (p_set_key_type == KEY_DES_OR_3DES_ISO))
                    {
                        rc = SCARD_DESFIRE.ChangeKey24(scard.hCard, 0, set_key_buffer, null);
                    }
                    else
                    if ((p_key_type == KEY_DES_OR_3DES_ISO) && (p_set_key_type == KEY_AES_ISO))
                    {
                        rc = SCARD_DESFIRE.ChangeKeyAes(scard.hCard, DF_APPLSETTING2_AES | 0, 0, set_key_buffer, null);
                    }
                    else
                    if ((p_key_type == KEY_AES_ISO) && (p_set_key_type == KEY_DES_OR_3DES))
                    {
                        rc = SCARD_DESFIRE.ChangeKey(scard.hCard, 0, set_key_buffer, null);
                    }
                    else
                    if ((p_key_type == KEY_AES_ISO) && (p_set_key_type == KEY_DES_OR_3DES_ISO))
                    {
                        rc = SCARD_DESFIRE.ChangeKey24(scard.hCard, 0, set_key_buffer, null);
                    }
                    else
                    if ((p_key_type == KEY_AES_ISO) && (p_set_key_type == KEY_AES_ISO))
                    {
                        rc = SCARD_DESFIRE.ChangeKeyAes(scard.hCard, DF_APPLSETTING2_AES | 0, 0, set_key_buffer, null);
                    }

                    if (rc != SCARD.S_SUCCESS)
                    {
                        Console.WriteLine("Change key failed");
                        if (!nfc_silent)
                        {
                            Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                        }
                        if (p_batch && p_continue)
                        {
                            goto batch_end;
                        }
                        goto failed;
                    }

                    switch (p_set_key_type)
                    {
                    case KEY_DES_OR_3DES: rc = SCARD_DESFIRE.Authenticate(scard.hCard, 0, set_key_buffer); break;

                    case KEY_DES_OR_3DES_ISO: rc = SCARD_DESFIRE.AuthenticateIso24(scard.hCard, 0, set_key_buffer); break;

                    case KEY_AES_ISO: rc = SCARD_DESFIRE.AuthenticateAes(scard.hCard, 0, set_key_buffer); break;

                    default: rc = -1; break;
                    }
                    if (rc != SCARD.S_SUCCESS)
                    {
                        Console.WriteLine("Authentication with new key failed");
                        if (!nfc_silent)
                        {
                            Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                        }
                        if (p_batch && p_continue)
                        {
                            goto batch_end;
                        }
                        goto failed;
                    }
                }
            }


            if (p_erase)
            {
                if (nfc_verbose)
                {
                    Console.WriteLine("Formating the card...");
                }

                rc = SCARD_DESFIRE.FormatPICC(scard.hCard);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Format PICC failed\n");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }
                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (p_set_key != null)
                {
                    if (nfc_verbose)
                    {
                        Console.WriteLine("Changing the key...");
                    }
                }

                if (!nfc_silent)
                {
                    Console.WriteLine("Card erase done...");
                }
            }


            if (p_prepare)
            {
                byte[] nfc_aid           = new byte[7];
                byte[] NFC_NDEF_7816_AID = new byte[7] {
                    0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01
                };
                nfc_aid = NFC_NDEF_7816_AID;
                byte[] cc_buffer = new byte[15];

                if (nfc_verbose)
                {
                    Console.WriteLine("Creating the NFC NDEF application...");
                }

                rc = SCARD_DESFIRE.CreateIsoApplication(scard.hCard,
                                                        NFC_NDEF_DESFIRE_DF_ID,
                                                        0xFF,
                                                        DF_APPLSETTING2_ISO_EF_IDS | 0,
                                                        NFC_NDEF_7816_DF_ID,
                                                        nfc_aid,
                                                        (byte)nfc_aid.Length);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Create application failed");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }

                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (nfc_verbose)
                {
                    Console.WriteLine("Entering the NFC NDEF directory...");
                }

                rc = SCARD_DESFIRE.SelectApplication(scard.hCard, NFC_NDEF_DESFIRE_DF_ID);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Select application failed");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }
                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (nfc_verbose)
                {
                    Console.WriteLine("Creating the NFC CC file...");
                }

                rc = SCARD_DESFIRE.CreateIsoStdDataFile(scard.hCard,
                                                        NFC_NDEF_DESFIRE_CC_EF_ID,
                                                        NFC_NDEF_7816_CC_EF_ID,
                                                        0,
                                                        0xEEEE,
                                                        cc_size);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Create CC file failed");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }

                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                ndef_size = 0;
                rc        = SCARD_DESFIRE.GetFreeMemory(scard.hCard, ref ndef_size);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Get free memory failed");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }
                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (p_size != 0)
                {
                    if (ndef_size < p_size)
                    {
                        Console.WriteLine("NDEF size=" + p_size + ", bigger than available space on card (" + ndef_size + ")\n", p_size, ndef_size);
                        if (!nfc_silent)
                        {
                            Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                        }
                        if (p_batch && p_continue)
                        {
                            goto batch_end;
                        }
                        goto failed;
                    }
                    ndef_size = (UInt32)p_size;
                }

                if (nfc_verbose)
                {
                    Console.WriteLine("Creating the NFC NDEF file...");
                }

                rc = SCARD_DESFIRE.CreateIsoStdDataFile(scard.hCard,
                                                        NFC_NDEF_DESFIRE_DATA_EF_ID,
                                                        NFC_NDEF_7816_DATA_EF_ID,
                                                        0,
                                                        0xEEEE,
                                                        ndef_size);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Create NDEF file failed: " + NFC_NDEF_DESFIRE_DATA_EF_ID + "-"
                                      + NFC_NDEF_7816_DATA_EF_ID + "-" + ndef_size);
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }
                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (nfc_verbose)
                {
                    Console.WriteLine("Populating the NFC CC file...\n");
                }

                cc_buffer[0]  = 0x00;
                cc_buffer[1]  = 0x0F;
                cc_buffer[2]  = NFC_NDEF_VERSION_2;
                cc_buffer[3]  = 0x00;
                cc_buffer[4]  = 0x3B;
                cc_buffer[5]  = 0x00;
                cc_buffer[6]  = 0x34;
                cc_buffer[7]  = NDEF_FILE_CONTROL_TAG;
                cc_buffer[8]  = 0x06;
                cc_buffer[9]  = (byte)(NFC_NDEF_7816_DATA_EF_ID >> 8);
                cc_buffer[10] = (byte)(NFC_NDEF_7816_DATA_EF_ID & 0x00FF);
                cc_buffer[11] = (byte)(ndef_size >> 8);
                cc_buffer[12] = (byte)(ndef_size & 0x00FF);
                cc_buffer[13] = 0x00;
                cc_buffer[14] = 0x00;

                rc = SCARD_DESFIRE.WriteData2(scard.hCard,
                                              NFC_NDEF_DESFIRE_CC_EF_ID,
                                              0,
                                              (UInt32)cc_buffer.Length,
                                              cc_buffer);
                if (rc != SCARD.S_SUCCESS)
                {
                    Console.WriteLine("Populate CC file failed\n");
                    if (!nfc_silent)
                    {
                        Console.WriteLine(SCARD_DESFIRE.GetErrorMessage(rc));
                    }
                    if (p_batch && p_continue)
                    {
                        goto batch_end;
                    }
                    goto failed;
                }

                if (!nfc_silent)
                {
                    Console.WriteLine("Card prepare done...\n");
                }
            }


batch_end:
            SCARD_DESFIRE.DetachLibrary(scard.hCard);
            scard.Disconnect();
            return;

            /* Error */
failed:
            if (scard.hCard != null)
            {
                SCARD_DESFIRE.DetachLibrary(scard.hCard);
            }
            scard.Disconnect();
            return;
        }