frozon / passbook

Passbook gem let's you create pkpass for passbook iOS 6
MIT License
235 stars 65 forks source link

Problems with JRuby? #60

Closed mungler closed 12 months ago

mungler commented 7 years ago

I hit problems using this Gem with latest JRuby 9.1.8.0 and latest JRuby-OpenSSL.

This monkey-patch may be useful - it addresses a bug in JRuby-OpenSSL (by explicitly passing pk7.data as a second argument to the write_smime method), as well as problems with str_debut and str_end being in a slightly different format in the JRuby output.

Hope its useful to someone :)

module Passbook
  class Signer

    # this works around a bug in JRuby-OpenSSL related to writing of SMIME,
    # as well as discrepancies in the SMIME output compared to what the 
    # passbook gem expects by default.

    def sign(data)
      wwdc  = OpenSSL::X509::Certificate.new File.read(wwdc_cert)
      pk7   = OpenSSL::PKCS7.sign key_hash[:cert], key_hash[:key], data.to_s, [wwdc], OpenSSL::PKCS7::BINARY | OpenSSL::PKCS7::DETACHED
      data  = OpenSSL::PKCS7.write_smime pk7, pk7.data

      str_debut = "filename=smime.p7s"
      data      = data[data.index(str_debut)+str_debut.length..data.length-1]
      str_end   = "\n------"
      data      = data[0..data.index(str_end)-1]

      Base64.decode64(data)
    end
  end
end
frozon commented 7 years ago

Hi, sorry for my late reply.

Instead of a monkey patch, Passbook::PKPass support a custom signer as second argument. So you could create a specific Signer let's say JRubySigner which would include your patch to get it working with JRuby and pass a new instance to it when you initialize your pkpass.

That would give you something like this

require 'jruby_signer'

my_signer = Passbook::JRubySigner.new
my_pass = Passbook::PKPass.new 'data', my_signer
...

Hope this will help

mungler commented 7 years ago

Good to know, thanks. I guess the gem could detect the platform and use a different default signer if its java?

frozon commented 7 years ago

Detecting ruby version could be tricky, what could be possible would be to add a new configuration var which would let you choose which signer to use in the initializer.

But one question would remain, I saw your issue on jruby-openssl, does this behavior is consistant across all version of jruby-openssl? And will it still be? What if we issue a new signer for jruby which would only work for the current release and won't on the next one.

mungler commented 7 years ago

Detecting JRuby is very simple:

RUBY_PLATFORM == "java"

But yes, I'm not sure about whether things may change between JRuby releases. The correct solution is to have JRuby behave the same as MRI. I may revisit this with the JRuby guys. Thanks!