drallgood / jpasskit

jPasskit is an Java™ implementation of the Apple™ PassKit Web Service.
Apache License 2.0
276 stars 109 forks source link

java.security.cert.CertificateException: X.509 not found #78

Closed kaanusha closed 7 years ago

kaanusha commented 7 years ago

import de.brendamour.jpasskit.signing.PKSigningInformationUtil;

String passKey = "C:\Certificate_1.p12"; String password = "1222"; String appleFile = "C:\AppleWorldwideDeveloperRelationsCertificationAuthority.pem";

PKSigningInformationUtil().loadSigningInformationFromPKCS12AndIntermediateCertificate(passKey, password, appleFile); is throwing java.security.cert.CertificateException: X.509 not found .

could you please help me in resolving this.

drallgood commented 7 years ago

@kaanusha Sorry, but I'm really not sure I can help you much there.

First of all, I need the full stack face to know which file this is happening for. Second, you should check, that your PKCS12 file actually contains a certificate. You can do this for example using the openssl command line tool. No idea how that works on Windows, though.

kaanusha commented 7 years ago

Thank you for the fast response..!! I am using one of the methods provided by JPasskit Framework classes for signing the certificates.

As i mentioned in earlier post, i am just passing the certificates - .p12, .pem paths and the password to the Jpasskit method.

Below are the code snippets of the methods and their inner methods .

Jpasskit method , I am calling from my code is: public PKSigningInformation loadSigningInformationFromPKCS12AndIntermediateCertificate(final String pkcs12KeyStoreFilePath, final String keyStorePassword, final String appleWWDRCAFilePath) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException, NoSuchProviderException, UnrecoverableKeyException {

    KeyStore pkcs12KeyStore = **loadPKCS12File**(pkcs12KeyStoreFilePath, keyStorePassword);
    Enumeration<String> aliases = pkcs12KeyStore.aliases();

    PrivateKey signingPrivateKey = null;
    X509Certificate signingCert = null;

    // find the certificate
    while (aliases.hasMoreElements()) {
        String aliasName = aliases.nextElement();

        Key key = pkcs12KeyStore.getKey(aliasName, keyStorePassword.toCharArray());
        if (key instanceof PrivateKey) {
            signingPrivateKey = (PrivateKey) key;
            Object cert = pkcs12KeyStore.getCertificate(aliasName);
            if (cert instanceof X509Certificate) {
                signingCert = (X509Certificate) cert;
                break;
            }
        }
    }

    X509Certificate appleWWDRCACert = **loadDERCertificate**(appleWWDRCAFilePath);
    return checkCertsAndReturnSigningInformationObject(signingPrivateKey, signingCert, appleWWDRCACert);
}

And below are the two internal methods, i am not getting even , which method is throwing this exception.

loadPKCS12File method :

public KeyStore loadPKCS12File(final String pathToP12, final String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { KeyStore keystore = KeyStore.getInstance("PKCS12");

    File p12File = new File(pathToP12);
    if (!p12File.exists()) {
        // try loading it from the classpath
        URL localP12File = PKFileBasedSigningUtil.class.getClassLoader().getResource(pathToP12);
        if (localP12File == null) {
            throw new FileNotFoundException("File at " + pathToP12 + " not found");
        }
        p12File = new File(localP12File.getFile());
    }
    InputStream streamOfFile = new FileInputStream(p12File);

    keystore.load(streamOfFile, password.toCharArray());
    IOUtils.closeQuietly(streamOfFile);
    return keystore;
}

loadDERCertificate method: public X509Certificate loadDERCertificate(final String filePath) throws IOException, CertificateException { FileInputStream certificateFileInputStream = null; try { File certFile = new File(filePath); if (!certFile.exists()) { // try loading it from the classpath URL localCertFile = PKFileBasedSigningUtil.class.getClassLoader().getResource(filePath); if (localCertFile == null) { throw new FileNotFoundException("File at " + filePath + " not found"); } certFile = new File(localCertFile.getFile()); } certificateFileInputStream = new FileInputStream(certFile);

        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
        Certificate certificate = certificateFactory.generateCertificate(certificateFileInputStream);
        if (certificate instanceof X509Certificate) {
            ((X509Certificate) certificate).checkValidity();
            return (X509Certificate) certificate;
        }
        throw new IOException("The key from '" + filePath + "' could not be decrypted");
    } catch (IOException ex) {
        throw new IOException("The key from '" + filePath + "' could not be decrypted", ex);
    } catch (NoSuchProviderException ex) {
        throw new IOException("The key from '" + filePath + "' could not be decrypted", ex);
    } finally {
        IOUtils.closeQuietly(certificateFileInputStream);
    }
}

Do we have any specifications that this kind of code will work(development/execution) only on particular OS?

drallgood commented 7 years ago

Hey @kaanusha Thanks for the reply. No, this should totally be working on any OS (even though I haven't tried it on Windows myself)

Could you please make sure that you have that bouncy castle libraries on your class path? The exception seems to be related to not being able to read x509 content

kaanusha commented 7 years ago

Thankyou @drallgood

I have resolved the issues with dependencies, and able to generate the pkpass. But this pass is not opening and getting saved to mobile wallet . I am hereby attaching pass file.Could you please help me here. regis.pkpass - using this I am able to save coupon to wallet from email, but not from (safari)my application pass.pkpass - using this not able to save couopn from both Email and Browser.

Passes.zip

drallgood commented 7 years ago

@kaanusha I looked at you passes and the first one is simply broken. I can't tell what exactly what, but it does not even validate.

The second one is valid and works fine. The fact that it does not work in Safari might have something to do with the mime type you're serving it with. Safari will only accept it if it's served with application/vnd.apple.pkpass mime type.

kaanusha commented 7 years ago

pass2.zip Hey @drallgood

I am bit confused here. :(

When you are saying first pass, are you referring regis.pkpass or pass.pkpass? Could you please tell me, so that i will take the correct pass and continue my work.

And I am attaching one more pkpass, could please validate this one as well.

Thank you!!

drallgood commented 7 years ago

@kaanusha The first one was pass.pkpass. That one doesn't work.

regis.pkpass works just fine

kaanusha commented 7 years ago

@drallgood Sorry to bother you these many times.

But I am very much new to Passkit/Passes and web developer. For the very first time I am working on the Web - app integration.

Pass.pkpass was created programtically using the de.brendamour.Jpasskit APIs. I am not getting why pass is getting broken.

And am reaching deadline badly , sir Could you please help me in finding the problem in this pass.

Hoping for best.. Thank you sir !!

drallgood commented 7 years ago

@kaanusha Without access to your code, I really can't help you much. The next thing I would check is the content of the p12 file and the AppleWorldwideDeveloperRelationsCertificationAuthority.pem

kaanusha commented 7 years ago

@drallgood

I am attaching here p12 and pem certificates . And from two days i am getting following exception. I have tried adding all the possible dependencies. Below is the exception: org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable java.lang.NoClassDefFoundError: org/bouncycastle/util/encoders/Base64 at org.bouncycastle.jcajce.provider.asymmetric.x509.PEMUtil.readPEMObject(Unknown Source) at org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.readPEMCertificate(Unknown Source) at org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.engineGenerateCertificate(Unknown Source) at java.security.cert.CertificateFactory.generateCertificate(Unknown Source) at de.brendamour.jpasskit.signing.PKSigningInformationUtil.loadDERCertificate(PKSigningInformationUtil.java:229) at de.brendamour.jpasskit.signing.PKSigningInformationUtil.loadSigningInformationFromPKCS12AndIntermediateCertificate(PKSigningInformationUtil.java:92) at de.brendamour.jpasskit.signing.PKSigningUtil.loadSigningInformationFromPKCS12FileAndIntermediateCertificateFile(PKSigningUtil.java:63)

Passkit iOS_Certificates.zip

drallgood commented 7 years ago

@kaanusha I'm not able to read the p12 file. And I'm not sure I need to since you should never share them with anybody else. If you have openssl installed, you can check this yourself: openssl pkcs12 -in ~/git/jpasskit/jpasskit/src/test/resources/passbook/jpasskittest.p12 -info you should be able to find both a certificate and a private key

Regarding your exception. Please double check your dependencies. Looks like you're either missing one of the bouncy castle ones or are using the wrong version of it.

vineetravi107 commented 7 years ago

@kaanusha Can you please tell how were you able to resolve "java.security.cert.CertificateException: X.509 not found" issue. As I see from the comment made on 24 Jan, you were able to figure out the issue but what did you follow to solve this?? I'm facing the same issue here..

vineetravi107 commented 7 years ago

@drallgood Any help would be very helpful..