public string contentString(ASN1Tag tag) { string val = ""; if (tag.Data != null) { val += " Len " + tag.Data.Length.ToString("X2") + ":" + tag.ToReadableString(); } return(val); }
/// <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); }
/// <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); }
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); } }
public string contentString(ASN1Tag tag) { return("NULL"); }
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); }
public string contentString(ASN1Tag tag) { return(ASCIIEncoding.ASCII.GetString(tag.Data)); }