示例#1
0
        static void ValidateHashes(PassKit p, Dictionary <string, string> discoveredHashes)
        {
            if (p.Manifest == null)
            {
                throw new MissingFieldException("PassKit is missing manifest.json or was unable to correctly parse it");
            }

            foreach (var file in discoveredHashes.Keys)
            {
                if (file.Equals("manifest.json", StringComparison.InvariantCultureIgnoreCase) ||
                    file.Equals("signature", StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                var discoveredHash = discoveredHashes[file];
                var expectedHash   = "";

                if (p.Manifest.ContainsKey(file))
                {
                    expectedHash = p.Manifest[file];
                }

                if (!discoveredHash.Equals(expectedHash, StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new FormatException("Manifest.json hash for " + file + " does not match the actual file in the PassKit!");
                }
            }
        }
示例#2
0
        static void ParsePassSet(PassKit p, JObject json)
        {
            if (json["headerFields"] != null && json["headerFields"] is JArray)
            {
                if (p.HeaderFields == null)
                {
                    p.HeaderFields = new PKPassFieldSet();
                }

                ParsePassFieldSet(json["headerFields"] as JArray, p.HeaderFields);
            }

            if (json["primaryFields"] != null && json["primaryFields"] is JArray)
            {
                if (p.PrimaryFields == null)
                {
                    p.PrimaryFields = new PKPassFieldSet();
                }

                ParsePassFieldSet(json["primaryFields"] as JArray, p.PrimaryFields);
            }

            if (json["secondaryFields"] != null && json["secondaryFields"] is JArray)
            {
                if (p.SecondaryFields == null)
                {
                    p.SecondaryFields = new PKPassFieldSet();
                }

                ParsePassFieldSet(json["secondaryFields"] as JArray, p.SecondaryFields);
            }

            if (json["auxiliaryFields"] != null && json["auxiliaryFields"] is JArray)
            {
                if (p.AuxiliaryFields == null)
                {
                    p.AuxiliaryFields = new PKPassFieldSet();
                }

                ParsePassFieldSet(json["auxiliaryFields"] as JArray, p.AuxiliaryFields);
            }

            if (json["backFields"] != null && json["backFields"] is JArray)
            {
                if (p.BackFields == null)
                {
                    p.BackFields = new PKPassFieldSet();
                }

                ParsePassFieldSet((JArray)json["backFields"], p.BackFields);
            }
        }
示例#3
0
        static void WriteManifest(PassKit pk, ZipFile zipFile, Dictionary <string, string> manifestHashes, X509Certificate2 signingCertificate, X509Certificate2Collection chainCertificates)
        {
            var json = new JObject();

            foreach (var key in manifestHashes.Keys)
            {
                json[key] = manifestHashes[key];
            }

            var data = Encoding.UTF8.GetBytes(json.ToString());


            zipFile.AddEntry("manifest.json", data);

            SignManifest(zipFile, data, signingCertificate, chainCertificates);
        }
示例#4
0
        private static string BuildQrCodeHtml(PassKit kit)
        {
            if (kit.Barcode == null || kit.Barcode.Message == null)
            {
                return(string.Empty);
            }

            QRCodeGenerator qrGenerator = new QRCodeGenerator();
            QRCodeData      qrCodeData  = qrGenerator.CreateQrCode("kit.Barcode.Message", QRCodeGenerator.ECCLevel.Q);
            QRCode          qrCode      = new QRCode(qrCodeData);
            MemoryStream    stream      = new MemoryStream();

            qrCode.GetGraphic(20).Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            var base64Image = System.Convert.ToBase64String(stream.ToArray());

            return($"<img id=\"qrcode\" width=\"120\" height=\"120\" src=\"data:image/png;base64,{base64Image}\">");
        }
示例#5
0
        static void ParseManifest(PassKit p, ZipEntry e, Dictionary <string, string> discoveredHashes)
        {
            JObject json = null;

            try
            {
                using (var ms = new MemoryStream())
                {
                    e.Extract(ms);

                    using (var sr = new StreamReader(ms))
                    {
                        ms.Position = 0;

                        var sha1 = CalculateSHA1(ms.GetBuffer(), Encoding.UTF8);
                        if (!discoveredHashes.ContainsKey(e.FileName.ToLower()))
                        {
                            discoveredHashes.Add(e.FileName.ToLower(), sha1);
                        }

                        var sj = sr.ReadToEnd();

                        json = JObject.Parse(sj);
                    }
                }
            }
            catch { }

            foreach (var prop in json.Properties())
            {
                var val  = prop.Value.ToString();
                var name = prop.Name.ToLower();

                if (!p.Manifest.ContainsKey(name))
                {
                    p.Manifest.Add(name, val);
                }
                else
                {
                    p.Manifest[name] = val;
                }
            }
        }
示例#6
0
        private static string BuildFields(PassKit kit, PKPassFieldSet fields)
        {
            if (fields == null)
            {
                return(string.Empty);
            }

            var sb = new StringBuilder();

            sb.Append("<dl>");

            foreach (PKPassField field in fields.Where(x => x != null))
            {
                if (string.IsNullOrEmpty(field.Label) && string.IsNullOrEmpty(field.Value))
                {
                    continue;
                }

                sb.Append($"<dt ");
                if (kit.LabelColor != null)
                {
                    sb.Append($"style=\"color: {kit.LabelColor} ;\"");
                }
                sb.Append($">");
                sb.Append($"{field.Label}</dt>");

                sb.Append($"<dd ");
                if (kit.ForegroundColor != null)
                {
                    sb.Append($"style=\"color: {kit.ForegroundColor} ;\"");
                }
                sb.Append($">");
                sb.Append($"{field.Value}</dd>");
            }

            sb.Append("</dl>");

            return(sb.ToString());
        }
示例#7
0
        public static string Convert(PassKit passKit)
        {
            var templateSb = new StringBuilder(GetBaseHtmlTemplate());

            templateSb.Replace("{{ backgroundColor }}", passKit.BackgroundColor.ToString());
            if (passKit.Logo != null)
            {
                templateSb.Replace("{{ logo }}", passKit.Logo.ToBase64());
            }

            if (passKit.Background != null)
            {
                templateSb.Replace("{{ backgroundimage }}", passKit.Logo.ToBase64());
            }

            templateSb.Replace("{{ headerFieldsHtml }}", BuildFields(passKit, passKit.HeaderFields));
            templateSb.Replace("{{ primaryFieldsHtml }}", BuildFields(passKit, passKit.PrimaryFields));
            templateSb.Replace("{{ secondaryFieldsHtml }}", BuildFields(passKit, passKit.SecondaryFields));
            templateSb.Replace("{{ auxiliaryFieldsHtml }}", BuildFields(passKit, passKit.AuxiliaryFields));

            templateSb.Replace("{{ qrCodeHtml }}", BuildQrCodeHtml(passKit));
            return(templateSb.ToString());
        }
示例#8
0
        static void ParsePassJson(PassKit p, ZipEntry e, Dictionary <string, string> discoveredHashes)
        {
            JObject json = null;

            try
            {
                using (var ms = new MemoryStream())
                {
                    e.Extract(ms);

                    ms.Position = 0;

                    var sha1 = CalculateSHA1(ms.GetBuffer(), Encoding.UTF8);
                    if (!discoveredHashes.ContainsKey(e.FileName.ToLower()))
                    {
                        discoveredHashes.Add(e.FileName.ToLower(), sha1);
                    }

                    using (var sr = new StreamReader(ms))
                        json = JObject.Parse(sr.ReadToEnd());
                }
            }
            catch { }

            if (json["passTypeIdentifier"] == null)
            {
                throw new MissingFieldException("PassKit must include a passTypeIdentifier field!");
            }

            if (json["formatVersion"] == null)
            {
                throw new MissingFieldException("PassKit must include a formatVersion field!");
            }

            if (json["organizationName"] == null)
            {
                throw new MissingFieldException("PassKit must include a organizationName field!");
            }

            if (json["serialNumber"] == null)
            {
                throw new MissingFieldException("PassKit must include a serialNumber field!");
            }

            if (json["teamIdentifier"] == null)
            {
                throw new MissingFieldException("PassKit must include a teamIdentifier field!");
            }

            if (json["description"] == null)
            {
                throw new MissingFieldException("PassKit must include a description field!");
            }

            p.PassTypeIdentifier = json["passTypeIdentifier"].Value <string>();
            p.FormatVersion      = json["formatVersion"].Value <int>();
            p.OrganizationName   = json["organizationName"].Value <string>();
            p.SerialNumber       = json["serialNumber"].Value <string>();
            p.TeamIdentifier     = json["teamIdentifier"].Value <string>();
            p.Description        = json["description"].Value <string>();


            if (json["webServiceURL"] != null)
            {
                p.WebServiceURL = json["webServiceURL"].ToString();
            }

            if (json["authenticationToken"] != null)
            {
                p.AuthenticationToken = json["authenticationToken"].ToString();
            }

            if (json["suppressStripShine"] != null)
            {
                p.SuppressStripShine = json["suppressStripShine"].Value <bool>();
            }

            if (json["foregroundColor"] != null)
            {
                p.ForegroundColor = PKColor.Parse(json["foregroundColor"].ToString());
            }

            if (json["backgroundColor"] != null)
            {
                p.BackgroundColor = PKColor.Parse(json["backgroundColor"].ToString());
            }

            if (json["labelColor"] != null)
            {
                p.LabelColor = PKColor.Parse(json["labelColor"].ToString());
            }

            if (json["logoText"] != null)
            {
                p.LogoText = json["logoText"].Value <string>();
            }

            if (json["relevantDate"] != null)
            {
                p.RelevantDate = json["relevantDate"].Value <DateTime>();
            }

            if (json["associatedStoreIdentifiers"] != null)
            {
                if (p.AssociatedStoreIdentifiers == null)
                {
                    p.AssociatedStoreIdentifiers = new List <string>();
                }

                var idarr = (JArray)json["associatedStoreIdentifiers"];
                foreach (var ida in idarr)
                {
                    p.AssociatedStoreIdentifiers.Add(ida.ToString());
                }
            }

            if (json["locations"] != null && json["locations"] is JArray)
            {
                foreach (JObject loc in (JArray)json["locations"])
                {
                    var pkl = new PKLocation();

                    if (loc["latitude"] == null)
                    {
                        throw new MissingFieldException("PassKit Location must include a latitude field!");
                    }

                    if (loc["longitude"] == null)
                    {
                        throw new MissingFieldException("PassKit Location must include a longitude field!");
                    }

                    pkl.Latitude  = loc["latitude"].Value <double>();
                    pkl.Longitude = loc["longitude"].Value <double>();

                    if (loc["altitude"] != null)
                    {
                        pkl.Altitude = loc["altitude"].Value <double>();
                    }

                    if (loc["relevantText"] != null)
                    {
                        pkl.RelevantText = loc["relevantText"].Value <string>();
                    }

                    if (p.Locations == null)
                    {
                        p.Locations = new PKLocationList();
                    }

                    p.Locations.Add(pkl);
                }
            }

            if (json["barcode"] != null)
            {
                var bc = json["barcode"] as JObject;

                if (p.Barcode == null)
                {
                    p.Barcode = new PKBarcode();
                }

                if (bc["message"] == null)
                {
                    throw new MissingFieldException("PassKit Barcode must include a message field!");
                }

                if (bc["format"] == null)
                {
                    throw new MissingFieldException("PassKit Barcode must include a format field!");
                }

                if (bc["messageEncoding"] == null)
                {
                    throw new MissingFieldException("PassKit Barcode must include a messageEncoding field!");
                }

                if (bc["altText"] != null)
                {
                    p.Barcode.AltText = bc["altText"].ToString();
                }

                p.Barcode.Message         = bc["message"].ToString();
                p.Barcode.MessageEncoding = bc["messageEncoding"].ToString();
                p.Barcode.Format          = (PKBarcodeFormat)Enum.Parse(typeof(PKBarcodeFormat), bc["format"].ToString());
            }

            if (json["eventTicket"] != null)
            {
                p.PassType = PKPassType.EventTicket;
                ParsePassSet(p, json["eventTicket"] as JObject);
            }

            if (json["boardingPass"] != null)
            {
                p.PassType = PKPassType.BoardingPass;
                ParsePassSet(p, json["boardingPass"] as JObject);
            }

            if (json["coupon"] != null)
            {
                p.PassType = PKPassType.Coupon;
                ParsePassSet(p, json["coupon"] as JObject);
            }

            if (json["generic"] != null)
            {
                p.PassType = PKPassType.Generic;
                ParsePassSet(p, json["generic"] as JObject);
            }

            if (json["storeCard"] != null)
            {
                p.PassType = PKPassType.StoreCard;
                ParsePassSet(p, json["storeCard"] as JObject);
            }
        }
示例#9
0
        public static PassKit Parse(Stream pkStream, bool loadHighResImages = true)
        {
            var discoveredHashes = new Dictionary <string, string>();

            var p = new PassKit();

            using (var zip = ZipFile.Read(pkStream))
            {
                foreach (var e in zip.Entries)
                {
                    if (e.IsDirectory)
                    {
                        continue;
                    }

                    PKLocalization pkLocalization = null;

                    /*var localeRx = new Regex(@"/{0,1}(?<locale>[a-zA-Z\-]{2,})\.lproj", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                     *
                     * var localeMatch = localeRx.Match(e.FileName);
                     *
                     * if (localeMatch != null && localeMatch.Success && localeMatch.Groups != null && localeMatch.Groups["locale"] != null)
                     * {
                     *  var localeName = localeMatch.Groups["locale"].Value.ToLower().Trim();
                     *
                     *  if (p.Localizations == null)
                     *      p.Localizations = new Dictionary<string, PKLocalization>();
                     *
                     *  if (!p.Localizations.ContainsKey(localeName))
                     *  {
                     *      pkLocalization = new PKLocalization();
                     *      p.Localizations.Add(localeName, pkLocalization);
                     *  }
                     *  else
                     *      pkLocalization = p.Localizations[localeName];
                     * }
                     * */


                    if (e.FileName.Equals("manifest.json", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Manifest == null)
                        {
                            p.Manifest = new PKManifest();
                        }

                        ParseManifest(p, e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("pass.json", StringComparison.InvariantCultureIgnoreCase))
                    {
                        ParsePassJson(p, e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("signature", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var signatureData = ReadStream(e, discoveredHashes);
                        if (!CheckManifest(signatureData))
                        {
                            throw new UnauthorizedAccessException("Signature is not valid");
                        }
                    }
                    else if (e.FileName.Equals("background.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (pkLocalization == null)
                        {
                            if (p.Background == null)
                            {
                                p.Background = new PKImage();
                            }

                            p.Background.Filename = e.FileName;
                            p.Background.Data     = ReadStream(e, discoveredHashes);
                        }
                        else
                        {
                            if (pkLocalization.Background == null)
                            {
                                pkLocalization.Background = new PKImage();
                            }

                            pkLocalization.Background.Filename = e.FileName;
                            pkLocalization.Background.Data     = ReadStream(e, discoveredHashes);
                        }
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Background == null)
                        {
                            p.Background = new PKImage();
                        }

                        p.Background.HighResFilename = e.FileName;
                        p.Background.HighResData     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("logo.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Logo == null)
                        {
                            p.Logo = new PKImage();
                        }

                        p.Logo.Filename = e.FileName;
                        p.Logo.Data     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Logo == null)
                        {
                            p.Logo = new PKImage();
                        }

                        p.Logo.HighResFilename = e.FileName;
                        p.Logo.HighResData     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("icon.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Icon == null)
                        {
                            p.Icon = new PKImage();
                        }

                        p.Icon.Filename = e.FileName;
                        p.Icon.Data     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Icon == null)
                        {
                            p.Icon = new PKImage();
                        }

                        p.Icon.HighResFilename = e.FileName;
                        p.Icon.HighResData     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("strip.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Strip == null)
                        {
                            p.Strip = new PKImage();
                        }

                        p.Strip.Filename = e.FileName;
                        p.Strip.Data     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Strip == null)
                        {
                            p.Strip = new PKImage();
                        }

                        p.Strip.HighResFilename = e.FileName;
                        p.Strip.HighResData     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("thumbnail.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Thumbnail == null)
                        {
                            p.Thumbnail = new PKImage();
                        }

                        p.Thumbnail.Filename = e.FileName;
                        p.Thumbnail.Data     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Thumbnail == null)
                        {
                            p.Thumbnail = new PKImage();
                        }

                        p.Thumbnail.HighResFilename = e.FileName;
                        p.Thumbnail.HighResData     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("footer.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Footer == null)
                        {
                            p.Footer = new PKImage();
                        }

                        p.Footer.Filename = e.FileName;
                        p.Footer.Data     = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Footer == null)
                        {
                            p.Footer = new PKImage();
                        }

                        p.Footer.HighResFilename = e.FileName;
                        p.Footer.HighResData     = ReadStream(e, discoveredHashes);
                    }
                }
            }

            ValidateHashes(p, discoveredHashes);

            return(p);
        }
示例#10
0
 public static void Write(PassKit passKit, string file, byte[] certificateData)
 {
     Write(passKit, file, new X509Certificate2(certificateData));
 }
示例#11
0
        static void ParsePassSet(PassKit p, JObject json)
        {
            if (json["primaryFields"] != null && json["primaryFields"] is JArray)
            {
                if (p.PrimaryFields == null)
                    p.PrimaryFields = new PKPassFieldSet();

                ParsePassFieldSet(json["primaryFields"] as JArray, p.PrimaryFields);
            }

            if (json["secondaryFields"] != null && json["secondaryFields"] is JArray)
            {
                if (p.SecondaryFields == null)
                    p.SecondaryFields = new PKPassFieldSet();

                ParsePassFieldSet(json["secondaryFields"] as JArray, p.SecondaryFields);
            }

            if (json["auxiliaryFields"] != null && json["auxiliaryFields"] is JArray)
            {
                if (p.AuxiliaryFields == null)
                    p.AuxiliaryFields = new PKPassFieldSet();

                ParsePassFieldSet(json["auxiliaryFields"] as JArray, p.AuxiliaryFields);
            }

            if (json["backFields"] != null && json["backFields"] is JArray)
            {
                if (p.BackFields == null)
                    p.BackFields = new PKPassFieldSet();

                ParsePassFieldSet((JArray)json["backFields"], p.BackFields);
            }
        }
示例#12
0
        static void ParsePassJson(PassKit p, ZipEntry e, Dictionary<string, string> discoveredHashes)
        {
            JObject json = null;

            try
            {
                using (var ms = new MemoryStream())
                {
                    e.Extract(ms);

                    ms.Position = 0;

                    var sha1 = CalculateSHA1(ms.GetBuffer(), Encoding.UTF8);
                    if (!discoveredHashes.ContainsKey(e.FileName.ToLower()))
                        discoveredHashes.Add(e.FileName.ToLower(), sha1);

                    using (var sr = new StreamReader(ms))
                        json = JObject.Parse(sr.ReadToEnd());
                }
            }
            catch { }

            if (json["passTypeIdentifier"] == null)
                throw new MissingFieldException("PassKit must include a passTypeIdentifier field!");

            if (json["formatVersion"] == null)
                throw new MissingFieldException("PassKit must include a formatVersion field!");

            if (json["organizationName"] == null)
                throw new MissingFieldException("PassKit must include a organizationName field!");

            if (json["serialNumber"] == null)
                throw new MissingFieldException("PassKit must include a serialNumber field!");

            if (json["teamIdentifier"] == null)
                throw new MissingFieldException("PassKit must include a teamIdentifier field!");

            if (json["description"] == null)
                throw new MissingFieldException("PassKit must include a description field!");

            p.PassTypeIdentifier = json["passTypeIdentifier"].Value<string>();
            p.FormatVersion = json["formatVersion"].Value<int>();
            p.OrganizationName = json["organizationName"].Value<string>();
            p.SerialNumber = json["serialNumber"].Value<string>();
            p.TeamIdentifier = json["teamIdentifier"].Value<string>();
            p.Description = json["description"].Value<string>();

            if (json["webServiceURL"] != null)
                p.WebServiceURL = json["webServiceURL"].ToString();

            if (json["authenticationToken"] != null)
                p.AuthenticationToken = json["authenticationToken"].ToString();

            if (json["suppressStripShine"] != null)
                p.SuppressStripShine = json["suppressStripShine"].Value<bool>();

            if (json["foregroundColor"] != null)
                p.ForegroundColor = PKColor.Parse(json["foregroundColor"].ToString());

            if (json["backgroundColor"] != null)
                p.BackgroundColor = PKColor.Parse(json["backgroundColor"].ToString());

            if (json["labelColor"] != null)
                p.LabelColor = PKColor.Parse(json["labelColor"].ToString());

            if (json["logoText"] != null)
                p.LogoText = json["logoText"].Value<string>();

            if (json["relevantDate"] != null)
                p.RelevantDate = json["relevantDate"].Value<DateTime>();

            if (json["associatedStoreIdentifiers"] != null)
            {
                if (p.AssociatedStoreIdentifiers == null)
                    p.AssociatedStoreIdentifiers = new List<string>();

                var idarr = (JArray)json["associatedStoreIdentifiers"];
                foreach (var ida in idarr)
                    p.AssociatedStoreIdentifiers.Add(ida.ToString());
            }

            if (json["locations"] != null && json["locations"] is JArray)
            {
                foreach (JObject loc in (JArray)json["locations"])
                {
                    var pkl = new PKLocation();

                    if (loc["latitude"] == null)
                        throw new MissingFieldException("PassKit Location must include a latitude field!");

                    if (loc["longitude"] == null)
                        throw new MissingFieldException("PassKit Location must include a longitude field!");

                    pkl.Latitude = loc["latitude"].Value<double>();
                    pkl.Longitude = loc["longitude"].Value<double>();

                    if (loc["altitude"] != null)
                        pkl.Altitude = loc["altitude"].Value<double>();

                    if (loc["relevantText"] != null)
                        pkl.RelevantText = loc["relevantText"].Value<string>();

                    if (p.Locations == null)
                        p.Locations = new PKLocationList();

                    p.Locations.Add(pkl);
                }
            }

            if (json["barcode"] != null)
            {
                var bc = json["barcode"] as JObject;

                if (p.Barcode == null)
                    p.Barcode = new PKBarcode();

                if (bc["message"] == null)
                    throw new MissingFieldException("PassKit Barcode must include a message field!");

                if (bc["format"] == null)
                    throw new MissingFieldException("PassKit Barcode must include a format field!");

                if (bc["messageEncoding"] == null)
                    throw new MissingFieldException("PassKit Barcode must include a messageEncoding field!");

                if (bc["altText"] != null)
                    p.Barcode.AltText = bc["altText"].ToString();

                p.Barcode.Message = bc["message"].ToString();
                p.Barcode.MessageEncoding = bc["messageEncoding"].ToString();
                p.Barcode.Format = (PKBarcodeFormat)Enum.Parse(typeof(PKBarcodeFormat), bc["format"].ToString());
            }

            if (json["eventTicket"] != null)
            {
                p.PassType = PKPassType.EventTicket;
                ParsePassSet(p, json["eventTicket"] as JObject);
            }

            if (json["boardingPass"] != null)
            {
                p.PassType = PKPassType.BoardingPass;
                ParsePassSet(p, json["boardingPass"] as JObject);
            }

            if (json["coupon"] != null)
            {
                p.PassType = PKPassType.Coupon;
                ParsePassSet(p, json["coupon"] as JObject);
            }

            if (json["generic"] != null)
            {
                p.PassType = PKPassType.Generic;
                ParsePassSet(p, json["generic"] as JObject);
            }

            if (json["storeCard"] != null)
            {
                p.PassType = PKPassType.StoreCard;
                ParsePassSet(p, json["storeCard"] as JObject);
            }
        }
示例#13
0
        static void ParseManifest(PassKit p, ZipEntry e, Dictionary<string, string> discoveredHashes)
        {
            JObject json = null;

            try
            {
                using (var ms = new MemoryStream())
                {
                    e.Extract(ms);

                    using (var sr = new StreamReader(ms))
                    {
                        ms.Position = 0;

                        var sha1 = CalculateSHA1(ms.GetBuffer(), Encoding.UTF8);
                        if (!discoveredHashes.ContainsKey(e.FileName.ToLower()))
                            discoveredHashes.Add(e.FileName.ToLower(), sha1);

                        var sj = sr.ReadToEnd();

                        json = JObject.Parse(sj);
                    }
                }
            }
            catch { }

            foreach (var prop in json.Properties())
            {
                var val = prop.Value.ToString();
                var name = prop.Name.ToLower();

                if (!p.Manifest.ContainsKey(name))
                    p.Manifest.Add(name, val);
                else
                    p.Manifest[name] = val;
            }
        }
示例#14
0
        public static PassKit Parse(Stream pkStream, bool loadHighResImages = true)
        {
            var discoveredHashes = new Dictionary<string, string>();

            var p = new PassKit();

            using (var zip = ZipFile.Read(pkStream))
            {
                foreach (var e in zip.Entries)
                {
                    if (e.IsDirectory)
                    {
                        continue;
                    }

                    PKLocalization pkLocalization = null;

                    /*var localeRx = new Regex(@"/{0,1}(?<locale>[a-zA-Z\-]{2,})\.lproj", RegexOptions.IgnoreCase | RegexOptions.Singleline);

                    var localeMatch = localeRx.Match(e.FileName);

                    if (localeMatch != null && localeMatch.Success && localeMatch.Groups != null && localeMatch.Groups["locale"] != null)
                    {
                        var localeName = localeMatch.Groups["locale"].Value.ToLower().Trim();

                        if (p.Localizations == null)
                            p.Localizations = new Dictionary<string, PKLocalization>();

                        if (!p.Localizations.ContainsKey(localeName))
                        {
                            pkLocalization = new PKLocalization();
                            p.Localizations.Add(localeName, pkLocalization);
                        }
                        else
                            pkLocalization = p.Localizations[localeName];
                    }
                     * */

                    if (e.FileName.Equals("manifest.json", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Manifest == null)
                            p.Manifest = new PKManifest();

                        ParseManifest(p, e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("pass.json", StringComparison.InvariantCultureIgnoreCase))
                    {
                        ParsePassJson(p, e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("signature", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var signatureData = ReadStream(e, discoveredHashes);
                        if (!CheckManifest(signatureData))
                            throw new UnauthorizedAccessException("Signature is not valid");
                    }
                    else if (e.FileName.Equals("background.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (pkLocalization == null)
                        {
                            if (p.Background == null)
                                p.Background = new PKImage();

                            p.Background.Filename = e.FileName;
                            p.Background.Data = ReadStream(e, discoveredHashes);
                        }
                        else
                        {
                            if (pkLocalization.Background == null)
                                pkLocalization.Background = new PKImage();

                            pkLocalization.Background.Filename = e.FileName;
                            pkLocalization.Background.Data = ReadStream(e, discoveredHashes);

                        }
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Background == null)
                            p.Background = new PKImage();

                        p.Background.HighResFilename = e.FileName;
                        p.Background.HighResData = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("logo.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Logo == null)
                            p.Logo = new PKImage();

                        p.Logo.Filename = e.FileName;
                        p.Logo.Data = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Logo == null)
                            p.Logo = new PKImage();

                        p.Logo.HighResFilename = e.FileName;
                        p.Logo.HighResData = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("icon.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Icon == null)
                            p.Icon = new PKImage();

                        p.Icon.Filename = e.FileName;
                        p.Icon.Data = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Icon == null)
                            p.Icon = new PKImage();

                        p.Icon.HighResFilename = e.FileName;
                        p.Icon.HighResData = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("strip.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Strip == null)
                            p.Strip = new PKImage();

                        p.Strip.Filename = e.FileName;
                        p.Strip.Data = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Strip == null)
                            p.Strip = new PKImage();

                        p.Strip.HighResFilename = e.FileName;
                        p.Strip.HighResData = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("thumbnail.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Thumbnail == null)
                            p.Thumbnail = new PKImage();

                        p.Thumbnail.Filename = e.FileName;
                        p.Thumbnail.Data = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Thumbnail == null)
                            p.Thumbnail = new PKImage();

                        p.Thumbnail.HighResFilename = e.FileName;
                        p.Thumbnail.HighResData = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("footer.png", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (p.Footer == null)
                            p.Footer = new PKImage();

                        p.Footer.Filename = e.FileName;
                        p.Footer.Data = ReadStream(e, discoveredHashes);
                    }
                    else if (e.FileName.Equals("*****@*****.**", StringComparison.InvariantCultureIgnoreCase) && loadHighResImages)
                    {
                        if (p.Footer == null)
                            p.Footer = new PKImage();

                        p.Footer.HighResFilename = e.FileName;
                        p.Footer.HighResData = ReadStream(e, discoveredHashes);
                    }
                }
            }

            ValidateHashes(p, discoveredHashes);

            return p;
        }
示例#15
0
        public static void Write(PassKit passKit, string file, X509Certificate2 signingCertificate, X509Certificate2Collection chainCertificates)
        {
            var manifestHashes = new Dictionary <string, string>();

            using (var zipFile = new ZipFile(file))
            {
                WritePass(passKit, zipFile, manifestHashes);

                if (passKit.Background != null)
                {
                    if (passKit.Background.Data != null && passKit.Background.Data.Length > 0)
                    {
                        zipFile.AddEntry("background.png", passKit.Background.Data);
                        manifestHashes.Add("background.png", CalculateSHA1(passKit.Background.Data));
                    }
                    if (passKit.Background.HighResData != null && passKit.Background.HighResData.Length > 0)
                    {
                        zipFile.AddEntry("*****@*****.**", passKit.Background.HighResData);
                        manifestHashes.Add("*****@*****.**", CalculateSHA1(passKit.Background.HighResData));
                    }
                }

                if (passKit.Logo != null)
                {
                    if (passKit.Logo.Data != null && passKit.Logo.Data.Length > 0)
                    {
                        zipFile.AddEntry("logo.png", passKit.Logo.Data);
                        manifestHashes.Add("logo.png", CalculateSHA1(passKit.Logo.Data));
                    }
                    if (passKit.Logo.HighResData != null && passKit.Logo.HighResData.Length > 0)
                    {
                        zipFile.AddEntry("*****@*****.**", passKit.Logo.HighResData);
                        manifestHashes.Add("*****@*****.**", CalculateSHA1(passKit.Logo.HighResData));
                    }
                }

                if (passKit.Icon != null)
                {
                    if (passKit.Icon.Data != null && passKit.Icon.Data.Length > 0)
                    {
                        zipFile.AddEntry("icon.png", passKit.Icon.Data);
                        manifestHashes.Add("icon.png", CalculateSHA1(passKit.Icon.Data));
                    }
                    if (passKit.Icon.HighResData != null && passKit.Icon.HighResData.Length > 0)
                    {
                        zipFile.AddEntry("*****@*****.**", passKit.Icon.HighResData);
                        manifestHashes.Add("*****@*****.**", CalculateSHA1(passKit.Icon.HighResData));
                    }
                }

                if (passKit.Strip != null)
                {
                    if (passKit.Strip.Data != null && passKit.Strip.Data.Length > 0)
                    {
                        zipFile.AddEntry("strip.png", passKit.Strip.Data);
                        manifestHashes.Add("strip.png", CalculateSHA1(passKit.Strip.Data));
                    }
                    if (passKit.Strip.HighResData != null && passKit.Strip.HighResData.Length > 0)
                    {
                        zipFile.AddEntry("*****@*****.**", passKit.Strip.HighResData);
                        manifestHashes.Add("*****@*****.**", CalculateSHA1(passKit.Strip.HighResData));
                    }
                }

                if (passKit.Thumbnail != null)
                {
                    if (passKit.Thumbnail.Data != null && passKit.Thumbnail.Data.Length > 0)
                    {
                        zipFile.AddEntry("thumbnail.png", passKit.Thumbnail.Data);
                        manifestHashes.Add("thumbnail.png", CalculateSHA1(passKit.Thumbnail.Data));
                    }
                    if (passKit.Thumbnail.HighResData != null && passKit.Thumbnail.HighResData.Length > 0)
                    {
                        zipFile.AddEntry("*****@*****.**", passKit.Thumbnail.HighResData);
                        manifestHashes.Add("*****@*****.**", CalculateSHA1(passKit.Thumbnail.HighResData));
                    }
                }

                if (passKit.Footer != null)
                {
                    if (passKit.Footer.Data != null && passKit.Footer.Data.Length > 0)
                    {
                        zipFile.AddEntry("footer.png", passKit.Footer.Data);
                        manifestHashes.Add("footer.png", CalculateSHA1(passKit.Footer.Data));
                    }
                    if (passKit.Footer.HighResData != null && passKit.Footer.HighResData.Length > 0)
                    {
                        zipFile.AddEntry("*****@*****.**", passKit.Footer.HighResData);
                        manifestHashes.Add("*****@*****.**", CalculateSHA1(passKit.Footer.HighResData));
                    }
                }


                WriteManifest(passKit, zipFile, manifestHashes, signingCertificate, chainCertificates);

                zipFile.Save();
            }
        }
示例#16
0
        static void WritePass(PassKit pk, ZipFile zipFile, Dictionary <string, string> manifestHashes)
        {
            var json = new JObject();

            json["passTypeIdentifier"] = pk.PassTypeIdentifier;
            json["formatVersion"]      = pk.FormatVersion;
            json["organizationName"]   = pk.OrganizationName;
            json["serialNumber"]       = pk.SerialNumber;
            json["teamIdentifier"]     = pk.TeamIdentifier;
            json["description"]        = pk.Description;

            if (pk.ForegroundColor != null)
            {
                json["foregroundColor"] = pk.ForegroundColor.ToString();
            }

            if (pk.BackgroundColor != null)
            {
                json["backgroundColor"] = pk.BackgroundColor.ToString();
            }

            if (pk.LabelColor != null)
            {
                json["labelColor"] = pk.LabelColor.ToString();
            }

            if (!string.IsNullOrEmpty(pk.LogoText))
            {
                json["logoText"] = pk.LogoText;
            }

            if (pk.RelevantDate.HasValue)
            {
                json["relevantDate"] = pk.RelevantDate.Value.ToString();
            }

            if (pk.AssociatedStoreIdentifiers != null && pk.AssociatedStoreIdentifiers.Count > 0)
            {
                json["associatedStoreIdentifiers"] = new JArray(pk.AssociatedStoreIdentifiers.ToArray());
            }

            if (pk.SuppressStripShine.HasValue)
            {
                json["suppressStripShine"] = pk.SuppressStripShine.Value;
            }

            if (!string.IsNullOrEmpty(pk.WebServiceURL))
            {
                json["webServiceURL"] = pk.WebServiceURL;
            }

            if (!string.IsNullOrEmpty(pk.AuthenticationToken))
            {
                json["authenticationToken"] = pk.AuthenticationToken;
            }

            if (pk.Locations != null && pk.Locations.Count > 0)
            {
                var jsonLocations = new JArray();

                foreach (var l in pk.Locations)
                {
                    var jLoc = new JObject();

                    jLoc["latitude"]  = l.Latitude;
                    jLoc["longitude"] = l.Longitude;

                    if (l.Altitude.HasValue)
                    {
                        jLoc["altitude"] = l.Altitude.Value;
                    }

                    if (!string.IsNullOrEmpty(l.RelevantText))
                    {
                        jLoc["relevantText"] = l.RelevantText;
                    }

                    jsonLocations.Add(jLoc);
                }

                json["locations"] = jsonLocations;
            }

            if (pk.Barcode != null)
            {
                var jsonBc = new JObject();

                jsonBc["message"]         = pk.Barcode.Message;
                jsonBc["format"]          = pk.Barcode.Format.ToString();
                jsonBc["messageEncoding"] = pk.Barcode.MessageEncoding;

                if (!string.IsNullOrEmpty(pk.Barcode.AltText))
                {
                    jsonBc["altText"] = pk.Barcode.AltText;
                }

                json["barcode"] = jsonBc;
            }

            var jSet = new JObject();

            if (pk.PrimaryFields != null && pk.PrimaryFields.Count > 0)
            {
                jSet["primaryFields"] = WritePassSet(pk.PrimaryFields);
            }

            if (pk.SecondaryFields != null && pk.SecondaryFields.Count > 0)
            {
                jSet["secondaryFields"] = WritePassSet(pk.SecondaryFields);
            }

            if (pk.AuxiliaryFields != null && pk.AuxiliaryFields.Count > 0)
            {
                jSet["auxiliaryFields"] = WritePassSet(pk.AuxiliaryFields);
            }

            if (pk.BackFields != null && pk.BackFields.Count > 0)
            {
                jSet["backFields"] = WritePassSet(pk.BackFields);
            }

            var setName = "eventTicket";

            switch (pk.PassType)
            {
            case PKPassType.BoardingPass:
                setName = "boardingPass";
                break;

            case PKPassType.Coupon:
                setName = "coupon";
                break;

            case PKPassType.EventTicket:
                setName = "eventTicket";
                break;

            case PKPassType.Generic:
                setName = "generic";
                break;

            case PKPassType.StoreCard:
                setName = "storeCard";
                break;
            }

            json[setName] = jSet;

            var data = System.Text.Encoding.UTF8.GetBytes(json.ToString());

            manifestHashes.Add("pass.json", CalculateSHA1(data, Encoding.UTF8));

            zipFile.AddEntry("pass.json", data);
        }
示例#17
0
        static void ValidateHashes(PassKit p, Dictionary<string, string> discoveredHashes)
        {
            if (p.Manifest == null)
                throw new MissingFieldException("PassKit is missing manifest.json or was unable to correctly parse it");

            foreach (var file in discoveredHashes.Keys)
            {
                if (file.Equals("manifest.json", StringComparison.InvariantCultureIgnoreCase)
                    || file.Equals("signature", StringComparison.InvariantCultureIgnoreCase))
                    continue;

                var discoveredHash = discoveredHashes[file];
                var expectedHash = "";

                if (p.Manifest.ContainsKey(file))
                    expectedHash = p.Manifest[file];

                if (!discoveredHash.Equals(expectedHash, StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new FormatException("Manifest.json hash for " + file + " does not match the actual file in the PassKit!");
                }
            }
        }
示例#18
0
 public static void Write(PassKit passKit, string file, string certificateFilename)
 {
     Write(passKit, file, new X509Certificate2(certificateFilename));
 }