tomasmcguinness / dotnet-passbook

A .Net Library for generating Apple Passbook (Wallet) files for iOS. Please get involved by creating pull requests and opening issues!
MIT License
318 stars 117 forks source link

Can't get the pass to be signed #161

Closed hjavaher closed 2 years ago

hjavaher commented 2 years ago

Hi, I can't get the pass to be signed by the certificates and I'm at a loss of what to do next and what I'm doing wrong. Can anyone help point me to a direction please? I have the following code (copied straight from the example provided)

I've confirmed that my certificate is valid and contains the private key and I've downloaded and tried every apple wwdr certificate.

            PassGenerator generator = new PassGenerator();

            PassGeneratorRequest request = new PassGeneratorRequest();
            request.PassTypeIdentifier = "pass.com.varyan.0exqz";
            request.TeamIdentifier = "RW121242";
            request.SerialNumber = "121212";
            request.Description = "My first pass";
            request.OrganizationName = "0EXQ";
            request.LogoText = "0EXQZ Pass";

            request.BackgroundColor = "#FFFFFF";
            request.LabelColor = "#000000";
            request.ForegroundColor = "#000000";

            var fileName = _env.WebRootPath + "AppleWWDRCA.cer";
            var applecertbytes = await System.IO.File.ReadAllBytesAsync(fileName);
            request.AppleWWDRCACertificate = new X509Certificate2(applecertbytes);

            fileName = _env.WebRootPath + "pass_nocommon.p12";
            var passCertbytes = await System.IO.File.ReadAllBytesAsync(fileName);
            request.PassbookCertificate = new X509Certificate2(passCertbytes, "Test123!@#");

            request.Images.Add(PassbookImage.Icon, System.IO.File.ReadAllBytes(_env.WebRootPath + ("icon.png")));
            request.Images.Add(PassbookImage.Icon2X, System.IO.File.ReadAllBytes(_env.WebRootPath + ("icon@2x.png")));
            request.Images.Add(PassbookImage.Icon3X, System.IO.File.ReadAllBytes(_env.WebRootPath + ("icon@3x.png")));

            request.Style = PassStyle.Generic;
            request.AddPrimaryField(new StandardField("origin", "San Francisco", "SFO"));
            request.AddPrimaryField(new StandardField("destination", "London", "LDN"));

            request.AddSecondaryField(new StandardField("boarding-gate", "Gate", "A55"));

            request.AddAuxiliaryField(new StandardField("seat", "Seat", "G5"));
            request.AddAuxiliaryField(new StandardField("passenger-name", "Passenger", "Thomas Anderson"));
            request.AddBarcode(BarcodeType.PKBarcodeFormatPDF417, "01927847623423234234", "ISO-8859-1", "01927847623423234234");

            byte[] generatedPass = generator.Generate(request);

            Debug.WriteLine(generatedPass);

            var contentType = "APPLICATION/octet-stream";
            var rfileName = "vnd.apple.pkpass";
            return File(generatedPass, contentType, rfileName);

It generates a pass but it doesn't sign it. I get the following validation result.

Screen Shot 2022-06-06 at 8 33 16 PM
tomasmcguinness commented 2 years ago

Hi.

At present, you must use the G4 WWDR certificate with new Passkit certificates.

If you generated your passkit certificate before the 27th of January, you use the G1 WWDR certificate.

I recommend regenerating your Passkit certificate and using the G4 WWDR.

Give that a try and report back.

alaafrarjah commented 2 years ago

Same issue here, I can't get the pass to be signed!

tomasmcguinness commented 2 years ago

@alaafrarjah What version of WWDR certificate are you using?

alaafrarjah commented 2 years ago

I tried every apple WWDR Certificate from G1 to G6 with no success. I did regenerate the Passkit certificate and used the G4 WWDR with no success.

alaafrarjah commented 2 years ago

`

public byte[] GenerateApplePass()
{
    PassGenerator generator = new PassGenerator();
    var PassbookCertificate = HttpContext.Current.Server.MapPath(PassCertificatePath);
    var WWDRCertificate = HttpContext.Current.Server.MapPath(WWDRCertificatePath);

    X509KeyStorageFlags flags = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable;

    var fileName = WWDRCertificate;
    var applecertbytes = System.IO.File.ReadAllBytes(fileName);
    X509Certificate2 certificateWWDR = new X509Certificate2(applecertbytes, "", flags);

    fileName = PassbookCertificate;
    var passCertbytes = System.IO.File.ReadAllBytes(fileName);
    X509Certificate2 certificatePass = new X509Certificate2(passCertbytes, "", flags);

    PassGeneratorRequest request = new PassGeneratorRequest
    {
        AppleWWDRCACertificate = certificateWWDR,
        PassbookCertificate = certificatePass,

        PassTypeIdentifier = " < PassTypeIdentifier >",
        TeamIdentifier = " < TeamIdentifier >",
        Description = " < Description > ",
        OrganizationName = " < OrganizationName > ",
        SerialNumber = "896666",

        LogoText = " < LogoText > ",
        BackgroundColor = "#FFFFFF",
        LabelColor = "#000000",
        ForegroundColor = "#000000",

        Style = PassStyle.Generic,

        SuppressStripShine = false,
    };

    request.Images.Add(PassbookImage.Icon, System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath(ImagePath + "Icon1x.png")));
    request.Images.Add(PassbookImage.Icon2X, System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath(ImagePath + "Icon2x.png")));
    request.Images.Add(PassbookImage.Icon3X, System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath(ImagePath + "Icon3x.png")));

    byte[] generatedPass = generator.Generate(request);

    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment;filename=apple.pkpass");
    Response.Charset = "";
    Response.ContentType = "application/octet-stream";

    Response.BinaryWrite(generatedPass);
    Response.Flush();
    Response.End();
}

`

tomasmcguinness commented 2 years ago

The G4 is the only one that will work with iOS now.

I notice that you're not using a password for your pass certificate. Are you sure it includes the private key?

alaafrarjah commented 2 years ago

@tomasmcguinness I tried with a password and without a password, same results. But regarding the private key, if I export from Keychain Access, I receive an error in Signature in date () as the private key does not have an expiry date. And if I export the Pass Type ID root certificate, I receive the mentioned errors.

tomasmcguinness commented 2 years ago

When you export from the keychain, are you including the private key?

Did you also read https://github.com/tomasmcguinness/pkpassvalidator/wiki/PassKit-certificate-contains-an-incorrect-value?

Would you mind sending me the pkpass file?

alaafrarjah commented 2 years ago

@tomasmcguinness When you export from the keychain, are you including the private key? "I suppose that"

alaafrarjah commented 2 years ago

@tomasmcguinness any updates or suggestions?

tomasmcguinness commented 2 years ago

Found the issues with the validator. The Subject and IssuerName strings were wrong. I think my processing is too simple.

However, your pass does open in iOS and I could add it to my wallet.

Were you experiencing a particular issue or just relying on pkpassvalidator? If the latter, I'm really sorry if you've wasted any time.

tomasmcguinness commented 2 years ago

I've pushed a new version of pkpassvalidator and the pass will now show as valid and signed correctly.

hjavaher commented 2 years ago

ok, I feel dumb now, I read the wiki attached pass certificate has incorrect values and generated another CSR without any names. This in combination with using G4 certificate fixed my issue. Also the validator shows the pass as valid now too (and I can add the pass to my iOS device)

Thank you again!!

alaafrarjah commented 2 years ago

Actually, I was relying on your validator, and it is not a waste of time as at least we discovered and resolved the issue.

Thank you for your support and for this amazing package, everything is working now.

tomasmcguinness commented 2 years ago

Great. Sorry again for any lost time! I should put a disclaimer on it :)

hjavaher commented 2 years ago

are you kidding, this troubleshooting pales in comparison to how much time you saved us with this awesome nugget package!!! Deeply thankful :)