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!"); } } }
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); } }
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); }
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}\">"); }
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; } } }
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()); }
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()); }
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); } }
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); }
public static void Write(PassKit passKit, string file, byte[] certificateData) { Write(passKit, file, new X509Certificate2(certificateData)); }
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); } }
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); } }
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; } }
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; }
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(); } }
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); }
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!"); } } }
public static void Write(PassKit passKit, string file, string certificateFilename) { Write(passKit, file, new X509Certificate2(certificateFilename)); }