Giter VIP home page Giter VIP logo

jpasskit's Introduction

jpasskit

jPasskit is an Java™ implementation of the Apple™ PassKit Web Service.

There are two separate projects:

  1. jPasskit - Which contains the Pass objects and useful utilities. It is designed to be included in existing Webservices, thus not including any request handling.
  2. jPasskit Server - Which contains an additional REST Webservice, that can be included in existing Applications that do not use their own Webservice already. Note: This is still no standalone implementation. Things like storing passes and handling device (un)registrations are left open for the Application to implement.

Current stable release: 0.4.2

Development Version: 0.4.3-SNAPSHOT Build Status Codacy Badge DepShield Badge

Installation

Using Maven

<dependency>
    <groupId>de.brendamour</groupId>
    <artifactId>jpasskit</artifactId>
</dependency>

or:

<dependency>
    <groupId>de.brendamour</groupId>
    <artifactId>jpasskit.server</artifactId>
</dependency>

The released artifacts are now available at Maven Central

Snapshot versions can be found here: https://oss.sonatype.org/content/repositories/snapshots/

Using Gradle

dependencies {
	api("de.brendamour:jpasskit:0.4.0")
}

or:

dependencies {
	api("de.brendamour:jpasskit.server:0.4.0")
}

The released artifacts are now available at Maven Central

Snapshot versions can be found here: https://oss.sonatype.org/content/repositories/snapshots/

Using jPasskit

Using jPasskit is pretty straight forward:

Creating a Pass

The class PKPass is the toplevel class. It represents the pass.json file. Everything else can just be added like one would add it on the JSON side.

Example:

PKPass pass = PKPass.builder()
		.pass(
				PKGenericPass.builder()
						.passType(PKPassType.PKStoreCard)
						.primaryFieldBuilder(
								PKField.builder()
										.key("balance")
										.label("balance")
										.value(20.0)
										.currencyCode("EUR")
						)
		)
		.barcodeBuilder(
				PKBarcode.builder()
						.format(PKBarcodeFormat.PKBarcodeFormatQR)
						.message("ABCDEFG")
						.messageEncoding(Charset.forName("utf-8"))
		)
		.formatVersion(1)
		.passTypeIdentifier("pass.some.passTypeIdentifier")
		.serialNumber("000000001")
		.teamIdentifier("myTeamId")
		.organizationName("OrgName")
		.logoText("MyPass")
		.description("My PassBook")
		.backgroundColor(Color.BLACK)
		.foregroundColor("rgb(255,255,255 )")
// ... and more initializations ...
		.build();

Providing pass templates

Usually, passes contain additional information that need to be included in the final, signed pass, e.g.

  • Images (icons, logos, background images)
  • Translations

jPasskit provides a flexible mechanism to provide such templates:

  • as a folder (using PKPassTemplateFolder)
  • as a set of streams (using PKPassTemplateInMemory)
  • using your own implementation (implementing IPKPassTemplate)

Folder-based templates (standard approach)

In order to use an existing folder on the file system as you pass's template, you create an instance of PKPassTemplateFolder using the path to your folder as argument:

IPKPassTemplate pkPassTemplateFolder = new PKPassTemplateFolder(PASS_TEMPLATE_FOLDER);

The content of this directory is defined in the PassKit Developer Documentation.

That's it. When signing the pass, the contents of this folder will be copied into the pass.

Dynamic templates (in memory)

This approach requires more code, but is also more flexible. The template is stored as a list of input streams, whose content gets copied into the pass when it is signed and packaged.

It does not matter, where the stream comes from, but the data needs to be available when the template is used. For convenience, we provide methods to add several additional data types to the template:

pkPassTemplateInMemory.addFile(PKPassTemplateInMemory.PK_BACKGROUND, stream);
pkPassTemplateInMemory.addFile(PKPassTemplateInMemory.PK_BACKGROUND_RETINA, stringBuffer);
pkPassTemplateInMemory.addFile(PKPassTemplateInMemory.PK_ICON, file);
pkPassTemplateInMemory.addFile(PKPassTemplateInMemory.PK_ICON_RETINA, url);

As you can see, we're also providing static variables for the most common file names.

You can also add an optional locale parameter to the call, in which case the file will automatically be added only for the given language:

pkPassTemplateInMemory.addFile(PKPassTemplateInMemory.PK_ICON_RETINA, Locale.ENGLISH, url); 
//content from URL will be placed in "en.lproj/[email protected]"

Note: There are no checks, that the content of a provided file is valid. So if you'd provide a PDF file but store it as icon.png, it will not work.

Signing and Zipping a Pass

The PKSigningUtil contains all necessary methods to:

  1. Load the Pass Certificate
  2. Load the Apple Worldwide Developer Relations CA (AppleWWDRCA)
  3. Create the pass.json file
  4. Hash all files in the Pass directory and create the Manifest file (manifest.json)
  5. Sign the Manifest file
  6. ZIP the finished Pass directory

Example to do it all in one step:

PKSigningInformation pkSigningInformation = new  PKSigningInformationUtil().loadSigningInformationFromPKCS12AndIntermediateCertificate(keyStorePath,  keyStorePassword, appleWWDRCA);
PKPassTemplateFolder passTemplate = new PKPassTemplateFolder(template_path);
PKFileBasedSigningUtil pkSigningUtil = new PKFileBasedSigningUtil();
byte[] signedAndZippedPkPassArchive = pkSigningUtil.createSignedAndZippedPkPassArchive(pass, passTemplate, pkSigningInformation);

Using the jPasskit Server

The jPasskit Server doesn't provide a full fledged PassKit Web Service but merely the basics you need implement your own standalone server. Things like storing passes and registrations still need to be implemented according to your own needs (or added to an existing Application).

Setup

The set up and start the Server you need two things:

  1. Create a Java Property object containing at least the three keys 'rest.bindIP', 'rest.bindPort' and 'rest.ssl.enabled'. Note: For the Production mode, you'll have to enable SSL and provide the following 4 keys:
    • rest.ssl.keystore.path : The path to the keystore where the SSL certificate for this server is stored
    • rest.ssl.keystore.type : The type of this keystore (e.g. PKCS12 or JKS)
    • rest.ssl.keystore.password : The password to access the keystore
    • rest.ssl.key.password : The password to access the private key Apple requires all production passes to use SSL.
  2. An implementation of IPKRestletServerResourceFactory.

The IPKRestletServerResourceFactory is used to create instances of three classes: PKDeviceResource. PKPassResource, PKLogResource. You'll need to subclass each of these and provide your own implementations.

PKDeviceResource is used to register/unregister devices and to get the serialNumbers of changed passes.

PKPassResource is used to fetch the latest version of a pass.

PKPersonalizePassResource is used to store the signup information for a rewards program (see https://developer.apple.com/library/prerelease/content/documentation/UserExperience/Conceptual/PassKit_PG/PassPersonalization.html)

PKLogResource is used for the log messages, that the devices send in case of an error.

Then you create the server instance:

Properties serverConfigurationProperties = new Properties();
serverConfigurationProperties.put("rest.bindIP", "::");
serverConfigurationProperties.put("rest.bindPort", "8082");

IPKRestletServerResourceFactory pkRestletServerResourceFactory = new MyOwnPKRestletServerResourceFactory();
PKRestServer pkRestServer = new PKRestServer(serverConfigurationProperties, pkRestletServerResourceFactory);
try {
    pkRestServer.start();
} catch (Exception e) {
    e.printStackTrace();
}

That's it. Your web service is running. Just point your passes to the URL where the server is running.

About Personalized Passes and Rewards Programs

Apple provides a handy, albeit short, guide about how this works: https://developer.apple.com/library/prerelease/content/documentation/UserExperience/Conceptual/PassKit\_PG/PassPersonalization.html

The process in broad strokes works as follows:

  1. You create a personalizable pass (e.g. using jPasskit) for a user using a unique serialNumber
  2. The user adds the pass, and completes the signup form
  3. Your server gets a request to the personalization endpoint at webServiceURL/version/passes/passTypeIdentifier/serialNumber/personalize which ends up in the PKPersonalizePassResource.
  4. You store the provided information and link it to the serialNumber
  5. Next time the user's device downloads a new version of the pass, you provide a custom pass with his information (Make sure you DON'T provide a personalizable pass this time!)

jpasskit's People

Contributors

chris-maheu avatar cmspray avatar codacy-badger avatar dbeard avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar derekfangming avatar drallgood avatar jankoscak avatar joconagy avatar joostbaas avatar jozsef-nagy-epam avatar koenpunt avatar lassejacobs avatar ramyhardan avatar roamingthings avatar sbuljat avatar stepio avatar targeter avatar woolfel avatar zouabimourad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jpasskit's Issues

Please help me change content type

Hi drallgood,
I have created file successfully, but Passbook cannot download and add to app on iPhone.
I'm google and found the result is content type of the file must be "appication/vnn.apple.pkpass"
Could you tell me the way to build file *.pkpass with content type as above.
Thank you.

Question about keyStorePath

Hello,

I wrote some code to create and sign a pass but I have a problem with my parameter keyStorePath. Can you explain me the parameter keyStorePath ? I generated my 3 pems and I stored in my pem directory. I tried to use too my p12 in the keyStorePath but I have the same error. Do you an example ?
My code:
String keyStorePath = "/passbook/src/main/resources/pem";
String keyStorePassword = "test2";
PKSigningInformation pkSigningInformation = PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(
keyStorePath, keyStorePassword, APPLE_WWDRCA);

Indeed in the jpasskit code: when I call loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile() method, I have a null value: PKSigningUtil.class.getClassLoader().getResource(keyStorePath);
So, I suppose my keyStorePath parameter is wrong. Any idea ?

Error:
java.io.FileNotFoundException: File at /passbook/src/main/resources/pem/Certificats_octo_test.p12 not found
at de.brendamour.jpasskit.signing.PKSigningUtil.loadPKCS12File(PKSigningUtil.java:194)
at de.brendamour.jpasskit.signing.PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(PKSigningUtil.java:156)
at com.octo.passbook.PassSign.createPassAndSign(PassSign.java:34)
at com.octo.passbook.PassSignTest.createPassAndSignOK(PassSignTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Thanx

pathToPassTemplate = null

Hi,

I'm using jpasskit server for my web service but there is an attribute who is never assigned.
"pathToPassTemplate" in the constructor of "PKPassResource".
I put a setter in the class but I don't understand how your test can pass without.
When the value is null, it cause an Exception when you try to copy the folder to the temp folder.

Maybe i'm wrong, could you please explain me ?

Thank you !

my passes are not grouping

I use the same pass data, only change the serial number ,
when I add 2 passes to passbook with the same category and same type identifier, passbook must group them in one group; but it does NOT.
my passes are of category: generic
and type identifier: pass.com.shopzooky.dev

I pulled all logs and console logs from device, but nothing about passbook there,

getAssociatedStoreIdentifiers Needs To Return Integers

Using this and its creating a bad passbook that won't load. In the console I get:

10/26/12 3:35:13.056 PM MobileSafari[3631]: Invalid data error reading card pass.com.localcounselcollective.hearing/8a9315d93a86bd06013a86bf61160000402880ee3a2394a7013a239527aa00001351287109859. store id in associatedStoreIdentifiers array needs to be a number. Found object of class __NSCFString.

I think you need to change this to be an integer and it will work.

Replace ToStringBuilder.reflectionToString with rzwitserloot/lombok

Hello, guys,

Recently I've tried http://projectlombok.org/ and loved it.
Maybe we should use it instead of ToStringBuilder.reflectionToString ?

Reflection is slow but "reflectionToString" is easy. Lombok uses best from both worlds: no need to write your own implementation, just annotate the class and the lib enriches your bytecode.

Example is here:
http://jnb.ociweb.com/jnb/jnbJan2010.html#tostring

P.S.: I only use it for overriding the existing methods - do not like the idea of using specific plugins for IDE to fix the code highlighting.

Unable to parse Field value as a date.

All of my fields are just text, and the values are null that imply a date.

We expect dates in "W3C date time stamp format", either "Complete date plus hours and minutes" or "Complete date plus hours, minutes and seconds". For example, 1980-05-07T10:30-05:00.

pass

passes created by jpasskit can be open on mac mini but cannot be opened from safari via mail

I have created a pass that is mailed as an attachment and it does not open on the device .
It says safari cannot open this file where as it open on the mac.
1.What is the extension of passcertificate and WWDR certificate it supports on JPassKit ?
2.Should i provide passcertificate.pem and passkey.pem similar process while creating pass on mac using terminal commands ?
I have created pass.json, manifest.json(with all images, pass.json) , signed using WWDR.cer (even tried with WWDR.pem)passcertificate.p12 (tried even with passcertificate.cer) and zip it but it does not download on safari.
Please Help .Thanks in advance.

Getting this error = "java.lang.ClassCastException: org.bouncycastle.asn1.DERUnknownTag cannot be cast to org.bouncycastle.asn1.DERString"

I have included the jar files of this project and other jar files like bouncy castle etc, now I created a EventExample.java file on my own, so that I could create an Event.pkpass file, but I getting this error, I am attaching a snapshot of the error.

3

Also my EventExample.java code is here.Please take a look and help me out.

import java.awt.Color;
import java.nio.charset.Charset;
import java.util.ArrayList;

import de.brendamour.jpasskit.PKBarcode;
import de.brendamour.jpasskit.PKField;
import de.brendamour.jpasskit.PKPass;
import de.brendamour.jpasskit.enums.PKBarcodeFormat;
import de.brendamour.jpasskit.passes.PKStoreCard;
import de.brendamour.jpasskit.signing.PKSigningInformation;
import de.brendamour.jpasskit.signing.PKSigningUtil;

public class EventTicketExample {

public static void main(String[] args) throws Throwable
{
    PKPass pass = new PKPass();
    PKBarcode barcode = new PKBarcode();
    PKStoreCard storeCard = new PKStoreCard();
    ArrayList<PKField> primaryFields = new ArrayList<PKField>();

    PKField balanceField = new PKField();
    balanceField.setKey( "balance" );
    balanceField.setLabel( "balance" );
    balanceField.setValue( 20.0 );
    balanceField.setCurrencyCode( "EUR" );

    primaryFields.add( balanceField );

    barcode.setFormat( PKBarcodeFormat.PKBarcodeFormatQR );
    barcode.setMessage( "ABCDEFG" );
    barcode.setMessageEncoding( Charset.forName( "utf-8" ) );

    storeCard.setPrimaryFields( primaryFields );

    pass.setFormatVersion( 1 );
    pass.setPassTypeIdentifier( "pass.com.testetix.ticket" );
    pass.setSerialNumber( "000000002" );
    pass.setTeamIdentifier( "LSCA6RKZ57" );
    pass.setBarcode( barcode );
    pass.setOrganizationName( "Etix" );
    pass.setLogoText( "MyPass" );
    pass.setStoreCard( storeCard );
    pass.setDescription( "My PassBook" );
    pass.setBackgroundColorAsObject( Color.BLACK );
    //pass.setForegroundColor( "rgb(255,255,255 )" );

    String pkcs12KeyStoreFilePath = "/home/techie/etix/eclipse/eclipse_projects/Pass/resources/p12/PassbookCert.p12"; // This store the path for .p12 file path
    String keyStorePassword = ""; // This stores the password for the key file
    String appleWWDRCA = "/home/techie/etix/eclipse/eclipse_projects/Pass/resources/pem/WWDR.pem"; // This stores the WWDR certificate path

    String pathToTemplateDirectory = "/home/techie/etix/eclipse/eclipse_projects/Pass/resources/template"; // This stores the path to all the files that have to be zipped




    PKSigningInformation pkSigningInformation = PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(
            pkcs12KeyStoreFilePath, keyStorePassword, appleWWDRCA);
    byte[] passZipAsByteArray = PKSigningUtil.createSignedAndZippedPkPassArchive(pass, pathToTemplateDirectory, pkSigningInformation);
}

}

another iOS9 feature - multiple barcodes

It looks like for iOS9, barcode is changing to allow multiple barcodes. Here is the relevant specification from apple's developer website. I am working on implementing this.

On iOS 9 and later, the system prefers the contents from the barcodes key. It only uses the barcode key when the barcodes key is missing. If neither the barcode nor the barcodes keys are present, then the system does not display a barcode.

Furthermore, the barcodes array lets you specify fallbacks for your barcode. The system uses the first valid barcode dictionary in the array. Note that the PKBarcodeFormatQR, PKBarcodeFormatPDF417, PKBarcodeFormatAztec, and PKBarcodeFormatCode128 formats are all valid on iOS 9 and later; therefore, they do not need fallbacks.

To support older versions of iOS, use both the barcode and barcodes keys. The system automatically selects the barcodes array for iOS 9.0 and later, and uses the barcode dictionary for iOS 8.0 and earlier.

Issue with bouncy castle lib

Hi, I have a problem with redeploying my project after small changes, I'm receiving error on bouncycastle lib, please see below:
at org.bouncycastle.asn1.DERObjectIdentifier.fromOctetString(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.createPrimitiveDERObject(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildEncodableVector(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildDEREncodableVector(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
at java.security.KeyStore.load(KeyStore.java:1214)

I'm just wondering that have anyone else had similar issues? There is no problem after fresh boot of glassfish, everything works just fine. But after redeployment nothing works.

Thanks for any comments!

passbook pass is not opening in iphone

I'm testing the version 0.0.7 and 0.0.6. the test (switching path), especially this class PKSigningUtilTest the method testJson. You have successfully generated the pass.pkpass file, but when I try to open iPhone does not open, This using certificates found in test / java / resources / passbook, I could tell what would be the way to fix it, if issue certificates? Thank you

Missing documentation for jPasskit Server properties

Great project. Hitting a few snags with the jPasskit Server component, though. Do we have any documentation or suggestions for the following properties? I apologize in advance if the questions are too basic.

rest.bindIP
rest.bindPort
rest.ssl.enabled
rest.ssl.keystore.path
rest.ssl.keystore.type
rest.ssl.keystore.password
rest.ssl.key.password

I couldn't find any IP or Port requirements on Apple's developer website. Do I just put localhost and the port that the server is running on?
I assume rest.ssl.enable must be set to "true", so rest.ssl.enabled = true
For keystore path, is it java-home/lib/security/cacerts?
For type, my certificate ends in .p12, so that's PKC12 for rest.ssl.keystore.type, correct?
rest.ssl.keystore.password is the password for cacerts above?
rest.ssl.key.password is the password used when generating the .p12 certificate?

If the above is correct, how do I add the .p12 file to cacerts?

Once this is clear, I intend to submit a Pull Request with this info.

loadPKCS12File() method throw exception on java 6

I modified this line : KeyStore keystore = KeyStore.getInstance("PKCS12",BouncyCastleProvider.PROVIDER_NAME);

to this one : KeyStore keystore = KeyStore.getInstance("PKCS12");;

just removed the provider name (BouncyCastleProvider.PROVIDER_NAME).

it was throwing IOException:
java.io.IOException: exception decrypting data - java.security.InvalidKeyException: Illegal key size
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.cryptData(Unknown Source)
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
at java.security.KeyStore.load(KeyStore.java:1185)
at de.brendamour.jpasskit.signing.PKSigningUtil.loadPKCS12File(PKSigningUtil.java:187)
at de.brendamour.jpasskit.signing.PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(PKSigningUtil.java:153)

Generated pass is invalid

I'm using a Glasfish server to generate the passes. All works fine e i can get the pass.pkpass file. The problem is when i try add the pass in Passbook app. It doesn't recognize the file. The same happens with Mail and Safari. What could be ? I think that can be some signature file fail, but i'm not sure. Could you help me please?

Generated pass not recognized in Mail app on iOS 7

Hi,

currently I'm having a problem with adding generated passes to the Passbook app on an iPhone. I've generated a pass and emailed it to the iPhone. When I download the atachement it displays as (null) on the phone and can't be added to the passbook app.

I'm using a PKCS#12 file and the WWDRCA.cer certificate to generate the pass. The same PKCS#12 file is used in another webservice to create demo passes. These passes are correctly recognized on the iPhone so I assume that the PKCS#12 file is valid.

For the pass I've provided the following information:

"formatVersion":1,
"serialNumber":"serial-14067964814945187177",
"passTypeIdentifier":"pass.my.demo.passbook.pass",
"authenticationToken":"0123456789abcdef",
"description":"Demo entitlement for use with Passbook",
"teamIdentifier":"<myIdentifier>",
"organizationName":"MyOrgl",
"foregroundColor":"rgb(255,255,255)",
"backgroundColor":"rgb(255,0,0)",
"labelColor":"rgb(0,0,0)",

Content of the directory:
icon.png
[email protected]
logo.png
[email protected]
pass.json

manifest.json and signature are later generated and added by JPassKit.

I'm using the following code to generate the pkpass file:

try {
    PKSigningInformation signingInformation =   
        PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(
                "./Testfiles/passbook.p12", "pswd", "./Testfiles/AppleWWDRCA.cer");
        byte[] archiveContents = PKSigningUtil.createSignedAndZippedPkPassArchive(pass, "./Testfiles/PassTemplate/", signingInformation);

        FileOutputStream fos = new FileOutputStream(new File("./Testfiles/pass.pkpass"));
        fos.write(archiveContents);
        fos.close();

        System.out.println("finished");

    } catch (UnrecoverableKeyException | NoSuchAlgorithmException
            | CertificateException | KeyStoreException
            | NoSuchProviderException | IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

I'm currently clueless why the generated pass wouldn't display on the iPhone. Thanks in advance for any help provided.

Best regards,
fugu2punkt0

One thing to add: I'm developing on a Windows machine so I can't use the signpass tool!

Pkpass generated with jpasskit is different than generated with signpass

Hi, I'm having a problem generating pkpass with jpasskit. I use Linux to develop and don't have an iPhone so my friend is the one who tests the pkpass.
When he tries to load the generated pkpass on his passbook the system log says:

Invalid data error reading pass pass.com.mycompany.passbook/kLGnVMHK. The passTypeIdentifier or teamIdentifier provided may not match your certificate, or the certificate trust chain could not be verified.

But if he takes the generated pkpass, removes signature and signs it with signpass the new pkpass is valid.
Any idea about why is this happening?

PS: I'm generating the pkpass files from a Glassfish Server over Linux.

The code I'm using:

PKSigningInformation pkSigningInformation = null;
byte[] passZipAsByteArray = null;
try {
pkSigningInformation = PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(keyStorePath, keyStorePassword,
appleWWDRCACertificatePath);

      passZipAsByteArray = PKSigningUtil.createSignedAndZippedPkPassArchive(pass, pathToTemplateDirectory, pkSigningInformation);
  }

Thanks.

Check certificate expiration

I was reading the code and noticed PKSigningUtil doesn't check certificate expiration by calling X509Certificate.checkValidity(). I also looked at bouncy castle's provider to see if they check the validity after the file is read into memory.

It might be a good idea to check for expiration. I'm happy to contribute a patch. One thought was to add a boolean parameter to loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile method. Something like boolean checkValidity. If it's true, the method would call the method. Calling X509Certificate.checkValidity() would throw an exception if it is expired, so not every would want that.

can't add to passbook????????

   it can't add to passbook.

This great code,but creat the pkpass error: The passTypeIdentifier or teamIdentifier provided may not match your certificate, or the certificate trust chain could not be verified.However i use the openssl creat the pkpass can add to passbook. when i use the jpasskit it can't add to passbook.

who can help me?
[email protected]

pass not getting added on Iphone Stimulator

Hi,
I have complied project & created simple java application to create pass by copy paste create pass code.
Also given exact TeamIdentifier, OrganizationName & PassTypeIdentifier.
pkpass file is created by passing byte[] passZipAsByteArray

Now when drag that file on iphone simulator safari browser I got an error dialog cant open the pass.
please help.

Build against java 7

Hi,

I'm trying to develop against your unstable release and noticed that you have your build target set to java 1.8. Building against java 1.7 would allow more projects to use your library and it doesn't seem that you are using any features that are java 8 specific.

We're stuck on java 7 for other reasons so we would really appreciate this.

Thanks again for writing this library!

iPhone is not recognizing .pkpass

Hi
I am generating .pkpass using below code, but it has not been recognized by iPhone. When I am sending email to my iPhone and attaching .pkpass as attachment, the attached .pkpass file showing null.
Please guide me.

Regards,
Kumar

Test code uses certificates, which are available only locally

Class de.brendamour.jpasskit.server.PKRestletServerResourceFactory contains constant path values for the certificates:

    protected static final String APPLE_WWDRCA_CERT_PATH = "/Users/patrice/Documents/bitzeche/Projects/passkit/AppleWWDRCA.pem";
    protected static final String PKCS12_FILE_PATH = "/Users/patrice/Documents/bitzeche/Projects/passkit/Certificates.p12";

Why aren't these certificates available as test resources? Is it a bug or more like a known limitation?

Support for NFC

Is there any plans to support NFC in future releases? The project I am on might need it in the future, so I'm willing to contribute to the feature.

thanks

NoClassDefFoundError with bouncycastle on Eclipse

Hi,

I am trying to use jpasskit with Google App Engine on Eclipse.

PKPass pass = createPKPass();
PKSigningInformation pkSigningInformation
         = PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(
                    keyStorePath, keyStorePassword, appleWWDRCA);

I am able to get the PKPass successfully using the example mentioned in the readme file, but when I try to get PKSigningInformation, I get the following error:

org.restlet.resource.UniformResource doCatch
WARNING: Exception or error caught in resource
java.lang.NoClassDefFoundError: org/bouncycastle/util/Store
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:171)
    at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
    at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:64)

I downloaded the jar file from http://trac.bitzeche.de/archiva/browse/de.brendamour/jpasskit/0.0.2

So, I was wondering if there is some problem in the jar file, or I am doing something wrong?

Thanks.

when creating a pass with 'webServiceUrl' it does not install on iphone

Scenario:
1-I created a pass of type generic and sent it to my email .
2- I opened it from iphone mail client and downloaded the .pkpass file, but my iphone did not recognize it as a pass file.

then I removed the 'webServiceUrl' from the pass, and did the same steps, and it works.

I tried hard to know why this is happening but could not find any thing,

I use jdk and java 6

In memory templates in stable release

Hi there,

Thanks for putting this library together! Do you have an ETA of when the in memory templates feature will make it to a stable release? Really looking forward to using them!

Cheers

File Paths Are Not Working in JBoss

I use JBoss as my app server. It uses this virtual file system. The need for the PKSigningUtil file to take absolute paths is not working. I have had to copy and modify all the functions to take URLs instead and just manipulate based on InputStreams. Any chance you would be interested in supporting that?

barcode on iPhone 4S and Android

The barcode on android and iphone 4s are not'm usabdo a QR, this is the code that generates me:

PKPass pass = new PKPass();
PKBarcode barcode = new PKBarcode();

barcode.setFormat(PKBarcodeFormat.PKBarcodeFormatQR);
barcode.setMessage("0006127418");
barcode.setMessageEncoding(Charset.forName("UTF-8"));
barcode.setAltText("0006127418");
pass.setBarcodes(Arrays.asList(barcode));

"barcodes": [
{
"format", "PKBarcodeFormatQR"
"altText": "0006127418"
"message": "0006127418"
"messageEncoding": "UTF-8"
}
],

Tested on iPhone 4S (ios 8) and Android (4.1.2) and the barcode is not seen.

Tested on iPhone 5, 5s, 6 and is right with ios 9

I'm using version 0.0.7

UnsupportedClassVersionError (Unable to load class)

Does this project have any dependencies that I need to be aware of? I am attempting to use jPasskit (server) on an existing Jersey webapp. When I try to run it, I get this error about not being able to load PKDeviceResource:

java.lang.UnsupportedClassVersionError: org/restlet/resource/ServerResource : Unsupported major.minor version 51.0 (unable to load class org.restlet.resource.ServerResource) (unable to load class de.brendamour.jpasskit.server.PKDeviceResource)
[...]

I am running JDK 1.6:
java version "1.6.0_30"
OpenJDK Runtime Environment (IcedTea6 1.13.1) (rhel-3.1.13.1.el6_5-x86_64)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)

I added the following dependencies:

                <dependency>
            <groupId>de.brendamour</groupId>
            <artifactId>jpasskit</artifactId>
            <version>0.0.7-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>de.brendamour</groupId>
            <artifactId>jpasskit.server</artifactId>
            <version>0.0.2-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.restlet.jee</groupId>
            <artifactId>org.restlet</artifactId>
            <version>2.3.4</version>
            <scope>compile</scope>
        </dependency>

Any ideas?

relevantDate field improperly populated

When using the relevantDate property, it's output value is a number instead of a W3C formatted string.

Steps:

  1. Create pass
  2. Set date: pass.setRelevantDate(new Date())
  3. View "relevantDate" in pass.json file

Expected:
"relevantDate":"2012-10-03T22:00:00-07:00"

Actual:
"relevantDate":1349326800000

Thanks for jpasskit!

Unexpected "register: true" when creating pass

Reported by hnthuan:

There is one problem with Barcode when create file pkpass.
When I call function setMessageEncoding( Charset.forName( "utf-8" ) ),I receive a string {"register":"true"} in file pass.json, so PassBook can't read file pkpass.
I fix this by edit your code, reply Charset by String, rebuild project and create new pkpass file that PassBook read successfully.
I'm not sure the message will be encode to UTF-8, so I hope you can check this bug for everyone can use your code more easy.

About the back of pass

I have created a new pass,when add it to the passbook,the back just show "Automatic Updates",i just want to know why "show on the locked screen" disappeared.

Charset filter

Hy I have an issue with setting barcode messageEncoding. I get this exception when i try to generate pass.json:

(org.codehaus.jackson.map.JsonMappingException) org.codehaus.jackson.map.JsonMappingException: No filter configured with id 'charsetFilter' (type java.lang.String) (through reference chain: de.brendamour.jpasskit.PKPass["barcode"]->de.brendamour.jpasskit.PKBarcode["messageEncoding"])

this is how i set barcode fields:

barcode.setFormat(PKBarcodeFormat.PKBarcodeFormatQR);
barcode.setMessage("NWYTOBOS1STCLASS");
barcode.setMessageEncoding( Charset.forName( "utf-8" ) );

If I try to generate pass without barcode it works fine.

Support generating json files in-memory

I was looking at how pkpass files are created and noticed it writes manifest.json and pass.json to JVM's temp folder. Some of our customers use virtual machines, so there might be corporate policies about using JVM temp folder. If I read the code correctly there's only a few places where it uses jackson to write to a file. Alternatively, it could write to a string instead.

I'd be happy to make the enhancement if others think that is a desirable feature.

thanks

JsonMappingException: Can not resolve PropertyFilter with id 'validateFilter'; no FilterProvider configured

In PKSigningUtil when calling createManifestJSONFile when using jackson-databind version >= 2.3.0.
Tried with both release 0.0.4 and 0.0.5-20140809 and got:

com.fasterxml.jackson.databind.JsonMappingException: Can not resolve PropertyFilter with id 'validateFilter'; no FilterProvider configured
at com.fasterxml.jackson.databind.ser.std.StdSerializer.findPropertyFilter(StdSerializer.java:274)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:401)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:27)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:114)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2866)
at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2272)
at de.brendamour.jpasskit.signing.PKSigningUtil.createManifestJSONFile(PKSigningUtil.java:381)
at de.brendamour.jpasskit.signing.PKSigningUtil.createSignedAndZippedPkPassArchive(PKSigningUtil.java:110)

Add validation for currency field value

When creating a PKField that will show a currency value, you can set the value as a string which doesn't cause a validation error but causes the pass to be broken.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.