class Lowdown::Certificate
This class is a wrapper around a certificate/key pair that returns values used by Lowdown
.
Constants
- DEVELOPMENT_ENV_EXTENSION
images.apple.com/certificateauthority/pdf/Apple_WWDR_CPS_v1.13.pdf
- PRODUCTION_ENV_EXTENSION
- UNIVERSAL_CERTIFICATE_EXTENSION
Attributes
@return [OpenSSL::X509::Certificate]
the Apple Push Notification certificate.
@return [OpenSSL::PKey::RSA, nil]
the private key that belongs to the certificate.
Public Class Methods
@param [Certificate, String] certificate_or_data
a configured Certificate or PEM data to construct a Certificate from.
@return [Certificate]
either the originally passed in Certificate or a new Certificate.
# File lib/lowdown/certificate.rb, line 16 def self.certificate(certificate_or_data) if certificate_or_data.is_a?(Certificate) certificate_or_data else from_pem_data(certificate_or_data) end end
A convenience method that initializes a Certificate
from PEM data.
@param [String] data
the PEM encoded certificate/key pair data.
@param [String] passphrase
a passphrase required to decrypt the PEM data.
@return (see Certificate#initialize)
# File lib/lowdown/certificate.rb, line 34 def self.from_pem_data(data, passphrase = nil) key = OpenSSL::PKey::RSA.new(data, passphrase) certificate = OpenSSL::X509::Certificate.new(data) new(certificate, key) end
A convenience method that initializes a Certificate
with the certificate and key from a SSL context object.
@param [OpenSSL::SSL::SSLContext] context
the context from which to initialize a Certificate.
@return (see Certificate#initialize)
# File lib/lowdown/certificate.rb, line 47 def self.from_ssl_context(context) new(context.cert, context.key) end
@param [OpenSSL::X509::Certificate] certificate
the Apple Push Notification certificate.
@param [OpenSSL::PKey::RSA] key
the private key that belongs to the certificate.
# File lib/lowdown/certificate.rb, line 57 def initialize(certificate, key = nil) @key, @certificate = key, certificate end
Public Instance Methods
@return [Boolean]
whether or not this Certificate is equal in contents to another Certificate.
# File lib/lowdown/certificate.rb, line 85 def ==(other) other.is_a?(Certificate) && other.to_pem == to_pem end
@return [String]
the App ID / app’s Bundle ID that this certificate is for.
# File lib/lowdown/certificate.rb, line 140 def app_bundle_id @certificate.subject.to_a.find { |key, *_| key == "UID" }[1] end
@return [Boolean]
whether or not the certificate supports the development (sandbox) environment (for development builds).
# File lib/lowdown/certificate.rb, line 111 def development? !extension(DEVELOPMENT_ENV_EXTENSION).nil? end
@return [Boolean]
whether or not the certificate supports the production environment (for Testflight & App Store builds).
# File lib/lowdown/certificate.rb, line 118 def production? !extension(PRODUCTION_ENV_EXTENSION).nil? end
@return [OpenSSL::SSL::SSLContext]
a SSL context, configured with the certificate/key pair, which is used to connect to the APN service.
# File lib/lowdown/certificate.rb, line 92 def ssl_context @ssl_context ||= OpenSSL::SSL::SSLContext.new.tap do |context| context.key = @key context.cert = @certificate end end
@return [String]
the certificate/key pair encoded as PEM data. Only used for testing.
# File lib/lowdown/certificate.rb, line 78 def to_pem [@key, @certificate].compact.map(&:to_pem).join("\n") end
@return [Array<String>]
a list of ‘topics’ that the certificate supports.
# File lib/lowdown/certificate.rb, line 127 def topics if universal? ext = extension(UNIVERSAL_CERTIFICATE_EXTENSION) seq = OpenSSL::ASN1.decode(OpenSSL::ASN1.decode(ext.to_der).value[1].value) seq.select.with_index { |_, index| index.even? }.map(&:value) else [app_bundle_id] end end
@return [Boolean]
whether or not the certificate is a Universal Certificate.
# File lib/lowdown/certificate.rb, line 104 def universal? !extension(UNIVERSAL_CERTIFICATE_EXTENSION).nil? end
Private Instance Methods
# File lib/lowdown/certificate.rb, line 151 def extension(oid) @certificate.extensions.find { |ext| ext.oid == oid } end