diff options
Diffstat (limited to 'lib/gitlab/ci/secure_files')
-rw-r--r-- | lib/gitlab/ci/secure_files/cer.rb | 56 | ||||
-rw-r--r-- | lib/gitlab/ci/secure_files/mobile_provision.rb | 85 | ||||
-rw-r--r-- | lib/gitlab/ci/secure_files/p12.rb | 56 | ||||
-rw-r--r-- | lib/gitlab/ci/secure_files/x509_name.rb | 15 |
4 files changed, 212 insertions, 0 deletions
diff --git a/lib/gitlab/ci/secure_files/cer.rb b/lib/gitlab/ci/secure_files/cer.rb new file mode 100644 index 00000000000..45d2898c29b --- /dev/null +++ b/lib/gitlab/ci/secure_files/cer.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module SecureFiles + class Cer + include Gitlab::Utils::StrongMemoize + + attr_reader :error + + def initialize(filedata) + @filedata = filedata + @error = nil + end + + def certificate_data + OpenSSL::X509::Certificate.new(@filedata) + rescue OpenSSL::X509::CertificateError => err + @error = err.to_s + nil + end + strong_memoize_attr :certificate_data + + def metadata + return {} unless certificate_data + + { + issuer: issuer, + subject: subject, + id: id, + expires_at: expires_at + } + end + strong_memoize_attr :metadata + + private + + def expires_at + certificate_data.not_before + end + + def id + certificate_data.serial.to_s + end + + def issuer + X509Name.parse(certificate_data.issuer) + end + + def subject + X509Name.parse(certificate_data.subject) + end + end + end + end +end diff --git a/lib/gitlab/ci/secure_files/mobile_provision.rb b/lib/gitlab/ci/secure_files/mobile_provision.rb new file mode 100644 index 00000000000..4ea74e20310 --- /dev/null +++ b/lib/gitlab/ci/secure_files/mobile_provision.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true +require 'cfpropertylist' + +module Gitlab + module Ci + module SecureFiles + class MobileProvision + include Gitlab::Utils::StrongMemoize + + attr_reader :error + + def initialize(filedata) + @filedata = filedata + end + + def decoded_plist + p7 = OpenSSL::PKCS7.new(@filedata) + p7.verify(nil, OpenSSL::X509::Store.new, nil, OpenSSL::PKCS7::NOVERIFY) + p7.data + rescue ArgumentError, OpenSSL::PKCS7::PKCS7Error => err + @error = err.to_s + nil + end + strong_memoize_attr :decoded_plist + + def properties + list = CFPropertyList::List.new(data: decoded_plist, format: CFPropertyList::List::FORMAT_XML).value + CFPropertyList.native_types(list) + rescue CFFormatError, CFPlistError, CFTypeError => err + @error = err.to_s + nil + end + strong_memoize_attr :properties + + def metadata + return {} unless properties + + { + id: id, + expires_at: expires_at, + platforms: properties["Platform"], + team_name: properties['TeamName'], + team_id: properties['TeamIdentifier'], + app_name: properties['AppIDName'], + app_id: properties['Name'], + app_id_prefix: properties['ApplicationIdentifierPrefix'], + xcode_managed: properties['IsXcodeManaged'], + entitlements: properties['Entitlements'], + devices: properties['ProvisionedDevices'], + certificate_ids: certificate_ids + } + end + strong_memoize_attr :metadata + + private + + def id + properties['UUID'] + end + + def expires_at + properties['ExpirationDate'] + end + + def certificate_ids + return [] if developer_certificates.empty? + + developer_certificates.map { |c| c.metadata[:id] } + end + + def developer_certificates + certificates = properties['DeveloperCertificates'] + return if certificates.empty? + + certs = [] + certificates.each_with_object([]) do |cert, obj| + certs << Cer.new(cert) + end + + certs + end + end + end + end +end diff --git a/lib/gitlab/ci/secure_files/p12.rb b/lib/gitlab/ci/secure_files/p12.rb new file mode 100644 index 00000000000..1006a4d05b2 --- /dev/null +++ b/lib/gitlab/ci/secure_files/p12.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module SecureFiles + class P12 + include Gitlab::Utils::StrongMemoize + + attr_reader :error + + def initialize(filedata, password = nil) + @filedata = filedata + @password = password + end + + def certificate_data + OpenSSL::PKCS12.new(@filedata, @password).certificate + rescue OpenSSL::PKCS12::PKCS12Error => err + @error = err.to_s + nil + end + strong_memoize_attr :certificate_data + + def metadata + return {} unless certificate_data + + { + issuer: issuer, + subject: subject, + id: serial, + expires_at: expires_at + } + end + strong_memoize_attr :metadata + + private + + def expires_at + certificate_data.not_before + end + + def serial + certificate_data.serial.to_s + end + + def issuer + X509Name.parse(certificate_data.issuer) + end + + def subject + X509Name.parse(certificate_data.subject) + end + end + end + end +end diff --git a/lib/gitlab/ci/secure_files/x509_name.rb b/lib/gitlab/ci/secure_files/x509_name.rb new file mode 100644 index 00000000000..659959b8ae5 --- /dev/null +++ b/lib/gitlab/ci/secure_files/x509_name.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module SecureFiles + class X509Name + def self.parse(x509_name) + x509_name.to_utf8.split(',').to_h { |a| a.split('=') } + rescue StandardError + {} + end + end + end + end +end |