Class: SignPass

Inherits:
Object
  • Object
show all
Defined in:
lib/sign_pass.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pass_url, certificate_url, certificate_password, wwdr_intermediate_certificate_path, output_url, compress_into_zip_file = true) ⇒ SignPass

Returns a new instance of SignPass.



62
63
64
65
66
67
68
69
# File 'lib/sign_pass.rb', line 62

def initialize(pass_url, certificate_url, certificate_password, wwdr_intermediate_certificate_path, output_url, compress_into_zip_file=true)
  self.pass_url                           = pass_url
  self.certificate_url                    = certificate_url
  self.certificate_password               = certificate_password
  self.wwdr_intermediate_certificate_path = wwdr_intermediate_certificate_path
  self.output_url                         = output_url
  self.compress_into_zip_file             = compress_into_zip_file
end

Instance Attribute Details

#certificate_passwordObject

Returns the value of attribute certificate_password.



59
60
61
# File 'lib/sign_pass.rb', line 59

def certificate_password
  @certificate_password
end

#certificate_urlObject

Returns the value of attribute certificate_url.



59
60
61
# File 'lib/sign_pass.rb', line 59

def certificate_url
  @certificate_url
end

#compress_into_zip_fileObject

Returns the value of attribute compress_into_zip_file.



59
60
61
# File 'lib/sign_pass.rb', line 59

def compress_into_zip_file
  @compress_into_zip_file
end

#manifest_urlObject

Returns the value of attribute manifest_url.



59
60
61
# File 'lib/sign_pass.rb', line 59

def manifest_url
  @manifest_url
end

#output_urlObject

Returns the value of attribute output_url.



59
60
61
# File 'lib/sign_pass.rb', line 59

def output_url
  @output_url
end

#pass_urlObject

Returns the value of attribute pass_url.



59
60
61
# File 'lib/sign_pass.rb', line 59

def pass_url
  @pass_url
end

#signature_urlObject

Returns the value of attribute signature_url.



59
60
61
# File 'lib/sign_pass.rb', line 59

def signature_url
  @signature_url
end

#temporary_directoryObject

Returns the value of attribute temporary_directory.



59
60
61
# File 'lib/sign_pass.rb', line 59

def temporary_directory
  @temporary_directory
end

#temporary_pathObject

Returns the value of attribute temporary_path.



59
60
61
# File 'lib/sign_pass.rb', line 59

def temporary_path
  @temporary_path
end

#wwdr_intermediate_certificate_pathObject

Returns the value of attribute wwdr_intermediate_certificate_path.



59
60
61
# File 'lib/sign_pass.rb', line 59

def wwdr_intermediate_certificate_path
  @wwdr_intermediate_certificate_path
end

Instance Method Details

#clean_ds_store_filesObject

Removes .DS_Store files if they exist



154
155
156
157
158
159
160
# File 'lib/sign_pass.rb', line 154

def clean_ds_store_files
  puts "Cleaning .DS_Store files"
  Dir.glob(self.temporary_path + "**/.DS_Store").each do |file|
    File.delete(file)
  end
  
end

#compress_pass_fileObject



199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/sign_pass.rb', line 199

def compress_pass_file
  puts "Compressing the pass"
  zipped_file = File.open(self.output_url, "w")
  
  Zip::ZipOutputStream.open(zipped_file.path) do |z|
    Dir.glob(self.temporary_path + "/**").each do |file|
      z.put_next_entry(File.basename(file))
      z.print IO.read(file)
    end
  end
  zipped_file
end

#copy_pass_to_temporary_locationObject

Copies the pass contents to the temporary location



147
148
149
150
# File 'lib/sign_pass.rb', line 147

def copy_pass_to_temporary_location
  puts "Copying pass to temp directory."
  FileUtils.cp_r(self.pass_url, self.temporary_directory)
end

#create_temporary_directoryObject

Creates a temporary place to work with the pass files without polluting the original



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/sign_pass.rb', line 133

def create_temporary_directory
  self.temporary_directory = Dir.mktmpdir
  puts "Creating temp dir at #{self.temporary_directory}"
  self.temporary_path = self.temporary_directory + "/" + self.pass_url.split("/").last
  
  # Check if the directory exists
  if File.directory?(self.temporary_path)
    # Need to clean up the directory
    FileUtils.rm_rf(self.temporary_path)
  end
  
end

#delete_temp_dirObject



212
213
214
# File 'lib/sign_pass.rb', line 212

def delete_temp_dir
  FileUtils.rm_rf(self.temporary_path)
end

#force_clean_raw_passObject



119
120
121
122
123
124
125
126
127
128
129
# File 'lib/sign_pass.rb', line 119

def force_clean_raw_pass
  puts "Force cleaning the raw pass directory."
  if File.exists?(File.join(self.pass_url, "/manifest.json"))
    File.delete(File.join(self.pass_url, "/manifest.json"))
  end
  
  if File.exists?(File.join(self.pass_url, "/signature"))
    File.delete(File.join(self.pass_url, "/signature"))
  end
  
end

#generate_json_manifestObject

Creates a json manifest where each files contents has a SHA1 hash



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/sign_pass.rb', line 164

def generate_json_manifest
  puts "Generating JSON manifest"
  manifest = {}
  # Gather all the files and generate a sha1 hash
  Dir.glob(self.temporary_path + "/**").each do |file|
    manifest[File.basename(file)] = Digest::SHA1.hexdigest(File.read(file))
  end
  
  # Write the hash dictionary out to a manifest file
  self.manifest_url = self.temporary_path + "/manifest.json"
  File.open(self.manifest_url, "w") do |f|
    f.write(manifest.to_json)
  end
  
end

#sign_manifestObject



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/sign_pass.rb', line 180

def sign_manifest
  puts "Signing the manifest"
  # Import the certificate
  p12_certificate = OpenSSL::PKCS12::new(File.read(self.certificate_url), self.certificate_password)
  wwdr_certificate = OpenSSL::X509::Certificate.new(File.read(self.wwdr_intermediate_certificate_path))
  
  # Sign the data
  flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED
  signed = OpenSSL::PKCS7::sign(p12_certificate.certificate, p12_certificate.key, File.read(self.manifest_url), [wwdr_certificate], flag)
  
  # Create an output path for the signed data
  self.signature_url = self.temporary_path + "/signature"
  
  # Write out the data
  File.open(self.signature_url, "w") do |f|
    f.syswrite signed.to_der
  end
end

#sign_pass!(force_clean_raw_pass = false) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/sign_pass.rb', line 72

def sign_pass!(force_clean_raw_pass=false)
  # Validate that requested contents are not a signed and expanded pass archive.
  self.validate_directory_as_unsigned_raw_pass(force_clean_raw_pass)
  
  # Get a temporary place to stash the pass contents
  self.create_temporary_directory
  
  # Make a copy of the pass contents to the temporary folder
  self.copy_pass_to_temporary_location
  
  # Clean out the unneeded .DS_Store files
  self.clean_ds_store_files
  
  # Build the json manifest
  self.generate_json_manifest
  
  # Sign the manifest
  self.sign_manifest
  
  # Package pass
  self.compress_pass_file
  
  # Clean up the temp directory
  #self.delete_temp_dir
end

#validate_directory_as_unsigned_raw_pass(force_clean = false) ⇒ Object

Ensures that the raw pass directory does not contain signatures



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/sign_pass.rb', line 102

def validate_directory_as_unsigned_raw_pass(force_clean=false)
  if force_clean
    force_clean_raw_pass
  end
  
  has_manifiest = File.exists?(File.join(self.pass_url, "/manifest.json"))
  puts "Raw pass has manifest? #{has_manifiest}"
  
  has_signiture = File.exists?(File.join(self.pass_url, "/signature"))
  puts "Raw pass has signature? #{has_signiture}"
      
  if has_signiture || has_manifiest
    raise RuntimeError, "#{self.pass_url} contains pass signing artificats that need to be removed before signing."
    
  end
end