Beispiel #1
0
        public string contentString(ASN1Tag tag)
        {
            string val = "";

            if (tag.Data != null)
            {
                val += " Len " + tag.Data.Length.ToString("X2") + ":" + tag.ToReadableString();
            }
            return(val);
        }
Beispiel #2
0
        /// <summary>
        /// Ritorna un sotto-tag dell'oggetto verificando che il suo numero di tag corrisponda a quello specificato (sotto forma di intero senza segno raw)
        /// </summary>
        /// <param name="tagNum">Il numero di sequenza  del sotto-tag (a partire da 0)</param>
        /// <param name="tagCheck">Il numero del sotto-tag da verificare</param>
        /// <returns>L'oggetto che contiene il sotto-tag</returns>
        public ASN1Tag Child(int tagNum, byte[] tagCheck)
        {
            ASN1Tag subTag = children[tagNum];

            if (!AreEqual(subTag.tag, tagCheck))
            {
                throw new Exception("Check del tag fallito");
            }
            return(subTag);
        }
Beispiel #3
0
        /// <summary>
        /// Ritorna un sotto-tag dell'oggetto verificando che il suo numero di tag corrisponda a quello specificato (sotto forma di intero senza segno raw)
        /// </summary>
        /// <param name="tagNum">Il numero di sequenza  del sotto-tag (a partire da 0)</param>
        /// <param name="tagCheck">Il numero del sotto-tag da verificare</param>
        /// <returns>L'oggetto che contiene il sotto-tag</returns>
        public ASN1Tag Child(int tagNum, uint tagCheck)
        {
            ASN1Tag tag = children[tagNum];

            if (tag.tagRawNumber != tagCheck)
            {
                throw new Exception("Check del tag fallito");
            }
            return(tag);
        }
Beispiel #4
0
 public string contentString(ASN1Tag tag)
 {
     try
     {
         //primi due numeri;
         List <int> nums = new List <int>();
         int        n2   = (tag.Data[0] % 40);
         int        n1   = ((tag.Data[0] - n2) / 40);
         nums.Add(n1);
         nums.Add(n2);
         int  pos    = 1;
         int  curNum = 0;
         bool doing  = false;
         while (pos < tag.Data.Length)
         {
             byte val = tag.Data[pos];
             curNum = (curNum << 7) | (val & 127);
             if ((val & 0x80) == 0)
             {
                 nums.Add(curNum);
                 curNum = 0;
                 doing  = false;
             }
             else
             {
                 doing = true;
             }
             pos++;
         }
         if (doing)
         {
             return("INVALID OID");
         }
         else
         {
             String res = "";
             foreach (int i in nums)
             {
                 res += i.ToString() + ".";
             }
             return(res.Substring(0, res.Length - 1));
         }
     }
     catch
     {
         return("INVALID OID");
     }
 }
        private IASSod(byte[] sod)
        {
            //Create asn1 structure of IAS sod object
            var asn1 = ASN1Tag.Parse(sod, true);
            //Take root element that represents all data signed
            var root = asn1.Child(0);

            root.Child(0, 06).Verify(OID.ToByteArray(OID.OIDsignedData)); //06 Verify that result is a OBJECT IDENTIFIER
            //Struttura che negli altri elementi verrà firmata
            SignedDataObject = root.DeepChild(1, 0, 2);
            SignedDataObject.Child(0, 06).Verify(OID.ToByteArray(OID.OIDldsSecurityObject)); //06 Verify that result is a OBJECT IDENTIFIER

            /*GET SIGNED DATA THAT CONTAINS HASHED INFORMATION OF:
             * - ID servizi
             * - Seriale carta
             * - Certificato utente
             * - Chiave pubblica di internal authentication
             * - Chiave pubblica di internal authentication per i servizi*/
            SignedData = SignedDataObject.DeepChild(1, 0).Child(0, 0x30); //0x30 Verify that result is a SEQUENCE
            //GET DOCUMENT SIGNER CERTIFICATE
            //This object can be parsed to X509Certificate2 class costrusctor
            DSCertificate = root.DeepChild(1, 0, 3).Child(0, 0x30);  //0x30 Verify that result is a SEQUENCE
            //GET SIGNER INFO
            var signerInfo = root.DeepChild(1, 0, 4).Child(0, 0x30); //0x30 Verify that result is a SEQUENCE

            /*GET INFORMATION OF ISSUER FROM SIGNER INFO
             * La struttura dati contenuta si avvicina alla seguente:
             * 0 SET (1 elem)
             *  0.0 SEQUENCE (2 elem)
             *      0.0.0 OBJECT IDENTIFIER (2.5.4.3 commonName (X.520 DN component))
             *      0.0.1 PrintableString (Italian Country Signer CA - TEST)
             * 1 SET (1 elem)
             *  1.0 SEQUENCE (2 elem)
             *      1.0.0 OBJECT IDENTIFIER (2.5.4.11 organizationalUnitName (X.520 DN component))
             *      1.0.1 PrintableString (National Electronic Center of State Police)
             * 2 SET (1 elem)
             *  2.0 SEQUENCE (2 elem)
             *      2.0.0 OBJECT IDENTIFIER (2.5.4.10 organizationName (X.520 DN component))
             *      2.0.1 PrintableString (Ministry of Interior)
             * 3 SET (1 elem)
             *  3.0 SEQUENCE (2 elem)
             *      3.0.0 OBJECT IDENTIFIER (2.5.4.6 countryName (X.520 DN component))
             *      3.0.1 PrintableString (IT)*/
            IssuerName = signerInfo.DeepChild(1).Child(0, 0x30); //0x30 Verify that result is a SEQUENCE

            /*GET INFORMATION OF SIGNER CERTIFICATE SERIAL NUMBER FROM DS CERT
             * La struttura dati contenuta si avvicina alla seguente:
             * 0 INTEGER (value of serial number)*/
            SerialNumber = signerInfo.DeepChild(1).Child(1, 0x02); //02 Verify that result is a INTEGER

            /*GET INFORMATION ABOUT SIGNER FROM DS CERT
             * La struttura dati contenuta si avvicina alla seguente:
             * 0 SEQUENCE (2 elem)
             *  0.0 OBJECT IDENTIFIER (1.2.840.113549.1.9.3 OIDcontentType)
             *  0.1 SET (1 elem)
             *      0.1.0 OBJECT IDENTIFIER (2.23.136.1.1.1 Security)
             * 1 SEQUENCE (2 elem)
             *  1.0 OBJECT IDENTIFIER (1.2.840.113549.1.9.4 OIDmessageDigest)
             *  1.1 SET (1 elem)
             *      1.1.0 OCTET STRING (F92C82AE7A944DCFFE4CCD0B6CAFA9D0134ED16EBEEFE6D9A44B641920F99BA9... (hash)) */
            SignatureAlgoritmIdentifier = signerInfo.Child(3, 0xA0);                                          //0xA0 Verify that result is a CONTEXT_SPECIFIC
            //Verify data structure of SignerInfo object
            SignatureAlgoritmIdentifier.DeepChild(0, 0).Verify(OID.ToByteArray(OID.OIDcontentType));          //Verify that node 0.0 is a OIDcontentType Object identifier
            SignatureAlgoritmIdentifier.DeepChild(0, 1, 0).Verify(OID.ToByteArray(OID.OIDldsSecurityObject)); //Verify that node 0.1.0 is a OIDldsSecurityObject Object identifier
            SignatureAlgoritmIdentifier.DeepChild(1, 0).Verify(OID.ToByteArray(OID.OIDmessageDigest));        //Verify that node 1.0 is a OIDmessageDigest Object identifier
            //Get message digest of Signer that is in the octect string object
            SignerMessageDigest = SignatureAlgoritmIdentifier.DeepChild(1, 1).Child(0, 04);                   //04 Verify that result is a OCTECT STRING
            //GET MESSAGE DIGEST SIGN ALGORYTM AND HASH ALGORYTM
            OIDDSMessageDigestSignAlgo = OID.ToString(signerInfo.DeepChild(4).Child(0, 06).Data);             //06 Verify that result is a OBJECT IDENTIFIER
            OIDDSMessageDigestHashAlgo = OID.ToString(signerInfo.DeepChild(2).Child(0, 06).Data);             //06 Verify that result is a OBJECT IDENTIFIER
            //Verify Signed data hash algoritm
            //SignedData.Child(0, 02).Verify(new byte[] { 0 });
            SignedData.DeepChild(1).Child(0, 06).Verify(OID.Encode(OIDDSMessageDigestHashAlgo)); //Verify hash algoritm

            /*GET SIGNATURE
             * La struttura dati contenuta si avvicina alla seguente:
             * 0 OCTET STRING (42C600B32BD5EFF0A684F65BD4526872AD3D4EADA3017A6E836736340BCCDA7DB9622...)*/
            Signature = signerInfo.Child(5, 04); //04 Verify that result is a OCTECT STRING
        }
        public byte[] ReadNIS(string reader)
        {
            // Connection to reader
            var sc = _peripheral.Connect(reader, SCardShareMode.Shared, SCardProtocol.Any);

            if (sc != SCardError.Success)
            {
                throw new Exception(string.Format("Could not connect to reader {0}:\n{1}",
                                                  reader,
                                                  SCardHelper.StringifyError(sc)));
            }
            try
            {
                CommandApdu  apdu;
                ResponseApdu rapdu;
                byte[]       receiveBuffer;

                /* 00 A4 - 04 0C 0D - A0 00 00 00 30 80 00 00 00 09 81 60 01 Selezione Applet CIE  */
                receiveBuffer = new byte[2];
                apdu          = new CommandApdu(IsoCase.Case4Short, _peripheral.ActiveProtocol)
                {
                    CLA  = 0x00,
                    INS  = 0XA4,
                    P1   = 0x04,
                    P2   = 0x0C,
                    Le   = 0x0D,
                    Data = new byte[] { (byte)0xA0, 0x00, 0x00, 0x00, 0x30, (byte)0x80, 0x00, 0x00, 0x00, 0x09, (byte)0x81, 0x60, 0x01 }
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);

                /* 00 A4 - 04 0C 06 - A0 00 00 00 00 39 Selezione DF_CIE */
                receiveBuffer = new byte[2];
                apdu          = new CommandApdu(IsoCase.Case4Short, _peripheral.ActiveProtocol)
                {
                    CLA  = 0x00,
                    INS  = 0XA4,
                    P1   = 0x04,
                    P2   = 0x0C,
                    Le   = 0x00,
                    Data = new byte[] { (byte)0xA0, 0x00, 0x00, 0x00, 0x00, 0x39 }
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);

                /* 00 B0 - 81 00 00 Lettura NIS */
                receiveBuffer = new byte[14];
                apdu          = new CommandApdu(IsoCase.Case2Short, _peripheral.ActiveProtocol)
                {
                    CLA = 0x00,
                    INS = 0XB0,
                    P1  = 0x81,
                    P2  = 0x00,
                    Le  = 0x00
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);
                rapdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, _peripheral.ActiveProtocol);
                var NIS_ID = rapdu.GetData();

                /* 00 B0 - 85 00 00 Lettura chiave pubblica - 1*/
                receiveBuffer = new byte[233];
                apdu          = new CommandApdu(IsoCase.Case2Short, _peripheral.ActiveProtocol)
                {
                    CLA = 0x00,
                    INS = 0XB0,
                    P1  = 0x85,
                    P2  = 0x00,
                    Le  = 0x00
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);
                rapdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, _peripheral.ActiveProtocol);
                var pubkey1 = rapdu.GetData();

                /* 00 B0 - 85 E7 00 - Lettura chiave pubblica - 2 */
                receiveBuffer = new byte[233];
                apdu          = new CommandApdu(IsoCase.Case2Short, _peripheral.ActiveProtocol)
                {
                    CLA = 0x00,
                    INS = 0XB0,
                    P1  = 0x85,
                    P2  = 0xE7,
                    Le  = 0x00
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);
                rapdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, _peripheral.ActiveProtocol);
                var pubkey2 = rapdu.GetData();
                //Combine pubkey1 and pubkey2 to obtain ASN1 structure that contain 2 children, modulus and exponent
                //that is used to create RSA crypto service provider
                var pubKeyAsn1 = ASN1Tag.Parse(pubkey1.Combine(pubkey2));

                /* 00 22 - 41 A4 06 - 80 01 02 84 01 83 - Selezione chiave int-auth */
                receiveBuffer = new byte[2];
                apdu          = new CommandApdu(IsoCase.Case4Short, _peripheral.ActiveProtocol)
                {
                    CLA  = 0x00,
                    INS  = 0x22,
                    P1   = 0x41,
                    P2   = 0xA4,
                    Le   = 0x02,
                    Data = new byte[] { 0x80, 0x01, 0x02, 0x84, 0x01, 0x83 }
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);

                /* Generate random to perform sign and verify */
                var challenge = ByteArrayOperations.GenerateRandomByteArray(8);

                /* 00 88 - 00 00 08 - hashChallenge 00 int-auth*/
                receiveBuffer = new byte[258];
                apdu          = new CommandApdu(IsoCase.Case4Short, _peripheral.ActiveProtocol)
                {
                    CLA  = 0x00,
                    INS  = 0x88,
                    P1   = 0x00,
                    P2   = 0x00,
                    Le   = 0x00,
                    Data = challenge
                };
                sc = _peripheral.Transmit(
                    SCardPCI.GetPci(_peripheral.ActiveProtocol),
                    apdu.ToArray(),
                    new SCardPCI(),
                    ref receiveBuffer);
                rapdu = new ResponseApdu(receiveBuffer, IsoCase.Case4Short, _peripheral.ActiveProtocol);
                var signedData = rapdu.GetData();

                //Verify challenge with public key
                using (var rsa = RSA.Create())
                {
                    var modulus = pubKeyAsn1.Child(0, 0x02).Data; // modulus. 02 Verify that result is a INTEGER
                    var exp     = pubKeyAsn1.Child(1, 0x02).Data; // exp. 02 Verify that result is a INTEGER
                    if (!rsa.PureVerify(challenge, signedData, modulus, exp))
                    {
                        throw new Exception("Unable to verify challenge");
                    }
                }

                //Read SOD data record
                var    idx  = 0;
                var    size = 0xe4;
                byte[] data;
                byte[] sodIASData = new byte[0];
                bool   sodLoaded  = false;
                while (!sodLoaded)
                {
                    var hexS = idx.ToString("X4");
                    receiveBuffer = new byte[233];
                    apdu          = new CommandApdu(IsoCase.Case4Short, _peripheral.ActiveProtocol)
                    {
                        CLA  = 0x00,
                        INS  = 0xB1,
                        P1   = 0x00,
                        P2   = 0x06,
                        Le   = 0x00,
                        Data = new byte[] {
                            0x54,
                            0x02,
                            byte.Parse(hexS.Substring(0, 2), System.Globalization.NumberStyles.HexNumber),
                            byte.Parse(hexS.Substring(2, 2), System.Globalization.NumberStyles.HexNumber)
                        }
                    };
                    sc = _peripheral.Transmit(
                        SCardPCI.GetPci(_peripheral.ActiveProtocol),
                        apdu.ToArray(),
                        new SCardPCI(),
                        ref receiveBuffer);
                    rapdu = new ResponseApdu(receiveBuffer, IsoCase.Case4Short, _peripheral.ActiveProtocol);
                    data  = rapdu.GetData();
                    var offset = 2;
                    if (data[1] > 0x80)
                    {
                        offset = 2 + (data[1] - 0x80);
                    }
                    var buf = data.SubArray(offset, data.Length - offset);
                    sodIASData = sodIASData.Combine(buf);
                    idx       += size;
                    if (data[2] != 0xe4)
                    {
                        sodLoaded = true;
                    }
                }
                //Create IAS ASN1 object
                var ias     = IASSod.Create(sodIASData);
                var isValid = ias.Verify(NIS_ID);

                //Verify integrity of data
                if (isValid)
                {
                    return(NIS_ID);
                }

                return(null);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally { _peripheral.Disconnect(SCardReaderDisposition.Reset); }
        }
Beispiel #7
0
 public string contentString(ASN1Tag tag)
 {
     return("NULL");
 }
Beispiel #8
0
        internal static ASN1Tag Parse(Stream s, UInt32 start, UInt32 length, ref UInt32 size, bool reparse)
        {
            UInt32 readPos = 0;

            if (readPos == length)
            {
                throw new Exception();
            }
            // leggo il tag
            List <byte> tagVal = new List <byte>();
            int         tag    = s.ReadByte();

            readPos++;
            tagVal.Add((byte)tag);
            if ((tag & 0x1f) == 0x1f)
            {
                // è un tag a più bytes; proseguo finchè non trovo un bit 8 a 0
                while (true)
                {
                    if (readPos == length)
                    {
                        throw new Exception();
                    }
                    tag = s.ReadByte();
                    readPos++;
                    tagVal.Add((byte)tag);
                    if ((tag & 0x80) != 0x80)
                    {
                        // è l'ultimo byte del tag
                        break;
                    }
                }
            }
            // leggo la lunghezza
            if (readPos == length)
            {
                throw new Exception();
            }
            UInt32 len = (UInt32)s.ReadByte();

            readPos++;
            if (len > 0x80)
            {
                UInt32 lenlen = len - 0x80;
                len = 0;
                for (int i = 0; i < lenlen; i++)
                {
                    if (readPos == length)
                    {
                        throw new Exception();
                    }
                    len = (UInt32)((len << 8) | (byte)s.ReadByte());
                    readPos++;
                }
            }
            else if (len == 0x80)
            {
                throw new Exception("Lunghezza indefinita non supportata");
            }
            size = (UInt32)(readPos + len);
            if (size > length)
            {
                throw new Exception("ASN1 non valido");
            }
            if (tagVal.Count == 1 && tagVal[0] == 0 && len == 0)
            {
                return(null);
            }
            byte[] data = new byte[len];
            s.Read(data, 0, (int)len);
            MemoryStream ms = new MemoryStream(data);
            // quando devo parsare i sotto tag??
            // in teoria solo se il tag è constructed, ma
            // spesso una octetstring o una bitstring sono
            // delle strutture ASN1...
            ASN1Tag        newTag       = new ASN1Tag(tagVal.ToArray());
            List <ASN1Tag> childern     = null;
            UInt32         parsedLen    = 0;
            bool           parseSubTags = false;

            if (newTag.tagConstructed)
            {
                parseSubTags = true;
            }
            else if (reparse && KnownTag(newTag.tag) == "OCTET STRING")
            {
                parseSubTags = true;
            }
            else if (reparse && KnownTag(newTag.tag) == "BIT STRING")
            {
                parseSubTags      = true;
                newTag.unusedBits = (byte)ms.ReadByte();
                parsedLen++;
            }

            if (parseSubTags)
            {
                childern = new List <ASN1Tag>();
                while (true)
                {
                    UInt32 childSize = 0;
                    try
                    {
                        ASN1Tag child = Parse(ms, start + readPos + parsedLen, (UInt32)(len - parsedLen), ref childSize, reparse);
                        if (child != null)
                        {
                            childern.Add(child);
                        }
                    }
                    catch
                    {
                        childern = null;
                        break;
                    }
                    parsedLen += childSize;
                    if (parsedLen > len)
                    {
                        childern = null;
                        break;
                    }
                    else if (parsedLen == len)
                    {
                        data = null;
                        break;
                    }
                }
            }
            newTag.startPos = start;
            newTag.endPos   = start + size;
            if (childern == null)
            {
                newTag.data = data;
            }
            else
            {
                newTag.children = childern;
            }
            return(newTag);
        }
Beispiel #9
0
 public string contentString(ASN1Tag tag)
 {
     return(ASCIIEncoding.ASCII.GetString(tag.Data));
 }