public CVCert(byte[] data) { ASN1Tag cert = ASN1Tag.Parse(data, false); cert.CheckTag(0x7F21); ASN1Tag certContent = cert.Child(0, 0x7F4E); Signature = cert.Child(1, 0x5F37).Data; Version = (int)new ByteArray(certContent.Child(0, 0x5F29).Data).ToUInt; Issuer = new ByteArray(certContent.Child(1, 0x42).Data).ToASCII; Name = new ByteArray(certContent.Child(3, 0x5F20).Data).ToASCII; ValidFrom = certContent.Child(5, 0x5F25).Data; Expire = certContent.Child(6, 0x5F24).Data; ASN1Tag PubKey = certContent.Child(2, 0x7F49); PubKeyAlgoOID = PubKey.Child(0, 0x06).Data; PubKeyModule = PubKey.Child(1, 0x81).Data; PubKeyExponent = PubKey.Child(2, 0x82).Data; ASN1Tag certTemplate = certContent.Child(4, 0x7F4C); CertificateTemplateOID = certTemplate.Child(0, 0x06).Data; CertificateTemplateValue = certTemplate.Child(1, 0x53).Data; RawCert = new ByteArray(data).Left((int)cert.EndPos); }
bool IssuedBy(X509Certificate2 cert, X509Certificate2 issuer) { try { if (!new ByteArray(cert.IssuerName.RawData).IsEqual(issuer.SubjectName.RawData)) { // verifico attributo per attributo var IssuerTag = ASN1Tag.Parse(cert.IssuerName.RawData, false); var SubjectTag = ASN1Tag.Parse(issuer.SubjectName.RawData, false); Dictionary <string, byte[]> IssuerComponents = new Dictionary <string, byte[]>(); Dictionary <string, byte[]> SubjectComponents = new Dictionary <string, byte[]>(); foreach (var c in IssuerTag.children) { var comp = c.Child(0); IssuerComponents[ASN1ObjIdDisplay.singleton.contentString(comp.Child(0))] = comp.Child(1).Data; } foreach (var c in SubjectTag.children) { var comp = c.Child(0); SubjectComponents[ASN1ObjIdDisplay.singleton.contentString(comp.Child(0))] = comp.Child(1).Data; } string[] keys = new string[IssuerComponents.Count]; IssuerComponents.Keys.CopyTo(keys, 0); foreach (var o in keys) { if (!SubjectComponents.ContainsKey(o)) { return(false); } var sub = UTF8Encoding.UTF8.GetString(SubjectComponents[o]); var iss = UTF8Encoding.UTF8.GetString(IssuerComponents[o]); if (sub != iss) { return(false); } IssuerComponents.Remove(o); SubjectComponents.Remove(o); } if (IssuerComponents.Count > 0 || SubjectComponents.Count > 0) { return(false); } } var akiExt = cert.Extensions["2.5.29.35"]; if (akiExt != null) { ASN1Tag akiTag = ASN1Tag.Parse(akiExt.RawData, false); var aki = akiTag.CheckTag(0x30); var aki2Tag = ASN1Tag.Parse(aki.Data, false); var akiData = aki2Tag.CheckTag(0x80).Data; var skiExt = issuer.Extensions["2.5.29.14"] as X509SubjectKeyIdentifierExtension; if (skiExt == null) { return(false); } if (skiExt.SubjectKeyIdentifier != HexDump(akiData)) { return(false); } } // verifico che la firma torni var certTag = ASN1Tag.Parse(cert.RawData, false); var signature = certTag.Child(2, 0x03).Data; var keyTag = ASN1Tag.Parse(issuer.PublicKey.EncodedKeyValue.RawData); var module = keyTag.Child(0, 2).Data; var pubExp = keyTag.Child(1, 2).Data; var rsa = new RSA(); var decSignature = ByteArray.RemoveBT1(rsa.RawRsa(module, pubExp, signature)); byte[] signedHash = null, certHash = null; var toHash = new ByteArray(cert.RawData).Sub((int)certTag.children[0].StartPos, (int)(certTag.children[0].EndPos - certTag.children[0].StartPos)); if (cert.SignatureAlgorithm.Value == "1.2.840.113549.1.1.5") { signedHash = rsa.RemoveSha1(decSignature); certHash = new SHA1().Digest(toHash); } else if (cert.SignatureAlgorithm.FriendlyName == "1.2.840.113549.1.1.11") { signedHash = rsa.RemoveSha256(decSignature); certHash = new SHA256().Digest(toHash); } else { throw new Exception("Algoritmo non supportato"); } if (!new ByteArray(signedHash).IsEqual(certHash)) { return(false); } return(true); } catch { } return(false); }
JObject readCardData(SmartCard smc, string r, string pin) { try { smc = new SmartCard(); // siamo all'interno dell'event handler del form, quindi per aggiornare la label devo eseguire il Message Loop Application.DoEvents(); // avvio la connessione al lettore richiedendo l'accesso esclusivo al chip if (!smc.Connect(r, Share.SCARD_SHARE_EXCLUSIVE, Protocol.SCARD_PROTOCOL_T1)) { System.Diagnostics.Debug.WriteLine("Errore in connessione: " + smc.LastSCardResult.ToString("X08")); label1.Text = "Errore in connessione: " + smc.LastSCardResult.ToString("X08"); JObject j = new JObject(); j.Add("Exception", "Errore in connessione: " + smc.LastSCardResult.ToString("X08")); jsonToReturn = j; return(j); } // Creo l'oggetto EAC per l'autenticazione e la lettura, passando la smart card su cui eseguire i comandi EAC a = new EAC(smc); // Verifico se il chip è SAC if (a.IsSAC()) { // Effettuo l'autenticazione PACE. // In un caso reale prima di avvare la connessione al chip dovrei chiedere all'utente di inserire il CAN txtStatus.Text += "chip SAC - PACE" + "\n"; a.PACE(pin); // a.PACE("641230", new DateTime(2022, 12, 30), "CA00000AA"); } else { // Per fare BAC dovrei fare la scansione dell'MRZ e applicare l'OCR all'imagine ottenuta. In questo caso ritorno errore. // a.BAC("641230", new DateTime(2022, 12, 30), "CA00000AA"); //a.BAC() // label1.Text = "BAC non disponibile"; txtStatus.Text += "chip BAC" + "\n"; } // Per poter fare la chip authentication devo prima leggere il DG14 var dg14 = a.ReadDG(DG.DG14); // Effettuo la chip authentication a.ChipAuthentication(); ASN1Tag asn = ASN1Tag.Parse(a.ReadDG(DG.DG11)); //creao il json da inviare alla webform var jsonObject = new JObject(); jsonObject.Add("nis", "?"); string nomeCognome = new ByteArray(asn.Child(1).Data).ToASCII.ToString(); jsonObject.Add("surname", nomeCognome.Split(new[] { "<<" }, StringSplitOptions.None)[0]); jsonObject.Add("name", nomeCognome.Split(new[] { "<<" }, StringSplitOptions.None)[1]); string codiceFiscale = new ByteArray(asn.Child(2).Data).ToASCII.ToString(); jsonObject.Add("fiscal_code", codiceFiscale); string residenza = new ByteArray(asn.Child(4).Data).ToASCII.ToString(); jsonObject.Add("res_addr", residenza.Split('<')[0]); jsonObject.Add("res_place", residenza.Split('<')[1]); jsonObject.Add("res_prov", residenza.Split('<')[2]); string birth = new ByteArray(asn.Child(3).Data).ToASCII.ToString(); jsonObject.Add("birth_place", birth.Split('<')[0]); jsonObject.Add("birth_prov", birth.Split('<')[1]); jsonObject.Add("birth_date", CF.GetDateFromFiscalCode(codiceFiscale)); txtStatus.Text += jsonObject.ToString(); // Leggo il DG2 contenente la foto var dg2 = a.ReadDG(DG.DG2); // Disconnessione dal chip smc.Disconnect(Disposition.SCARD_RESET_CARD); jsonToReturn = jsonObject; return(jsonObject); } catch (Exception e) { txtStatus.Text += "Eccezione: " + e.Message; JObject j = new JObject(); j.Add("Exception", e.Message); jsonToReturn = j; return(j); } }