pki_express 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitattributes +3 -0
- data/.gitignore +28 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +4 -0
- data/README.md +24 -0
- data/Rakefile +1 -0
- data/lib/pki_express.rb +48 -0
- data/lib/pki_express/auth_complete_result.rb +22 -0
- data/lib/pki_express/auth_start_result.rb +77 -0
- data/lib/pki_express/authentication.rb +285 -0
- data/lib/pki_express/base_signer.rb +55 -0
- data/lib/pki_express/cades_signature_starter.rb +242 -0
- data/lib/pki_express/command_error.rb +14 -0
- data/lib/pki_express/commands.rb +21 -0
- data/lib/pki_express/enum.rb +9 -0
- data/lib/pki_express/error_codes.rb +46 -0
- data/lib/pki_express/installation_not_found_error.rb +8 -0
- data/lib/pki_express/name.rb +48 -0
- data/lib/pki_express/pades_horizontal_align.rb +9 -0
- data/lib/pki_express/pades_measurement_units.rb +8 -0
- data/lib/pki_express/pades_page_optimization.rb +51 -0
- data/lib/pki_express/pades_page_orientation.rb +9 -0
- data/lib/pki_express/pades_paper_size.rb +21 -0
- data/lib/pki_express/pades_signature_starter.rb +232 -0
- data/lib/pki_express/pades_size.rb +17 -0
- data/lib/pki_express/pades_text_horizontal_align.rb +8 -0
- data/lib/pki_express/pades_vertical_align.rb +9 -0
- data/lib/pki_express/pades_visual_auto_positioning.rb +22 -0
- data/lib/pki_express/pades_visual_image.rb +52 -0
- data/lib/pki_express/pades_visual_manual_positioning.rb +17 -0
- data/lib/pki_express/pades_visual_positioning.rb +28 -0
- data/lib/pki_express/pades_visual_rectangle.rb +74 -0
- data/lib/pki_express/pades_visual_representation.rb +22 -0
- data/lib/pki_express/pades_visual_text.rb +35 -0
- data/lib/pki_express/pk_certificate.rb +62 -0
- data/lib/pki_express/pki_brazil_certificate_fields.rb +58 -0
- data/lib/pki_express/pki_brazil_certificate_types.rb +19 -0
- data/lib/pki_express/pki_express_config.rb +26 -0
- data/lib/pki_express/pki_express_operator.rb +216 -0
- data/lib/pki_express/pki_italy_certificate_fields.rb +16 -0
- data/lib/pki_express/pki_italy_certificate_types.rb +11 -0
- data/lib/pki_express/signature_finisher.rb +298 -0
- data/lib/pki_express/signature_start_result.rb +13 -0
- data/lib/pki_express/signature_starter.rb +115 -0
- data/lib/pki_express/signer.rb +106 -0
- data/lib/pki_express/standard_signature_policies.rb +36 -0
- data/lib/pki_express/timestamp_authority.rb +51 -0
- data/lib/pki_express/validation_error.rb +8 -0
- data/lib/pki_express/validation_item.rb +43 -0
- data/lib/pki_express/validation_results.rb +121 -0
- data/lib/pki_express/version.rb +3 -0
- data/lib/pki_express/version_manager.rb +21 -0
- data/pki_express.gemspec +27 -0
- metadata +129 -0
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
              class PadesVisualManualPositioning < PadesVisualPositioning
         | 
| 3 | 
            +
                attr_accessor :signature_rectangle
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(page_number=nil, measurement_units=nil, signature_rectangle=nil)
         | 
| 6 | 
            +
                  super(page_number, measurement_units)
         | 
| 7 | 
            +
                  @signature_rectangle = signature_rectangle
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def to_model
         | 
| 11 | 
            +
                  model = super
         | 
| 12 | 
            +
                  model['manual'] = @signature_rectangle&.to_model
         | 
| 13 | 
            +
                  model
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
              class PadesVisualPositioning
         | 
| 3 | 
            +
                attr_reader :measurement_units
         | 
| 4 | 
            +
                attr_accessor :page_number, :page_optimization
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(page_number=nil, measurement_units=nil)
         | 
| 7 | 
            +
                  @page_number = page_number
         | 
| 8 | 
            +
                  @measurement_units = measurement_units
         | 
| 9 | 
            +
                  @page_optimization = nil
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def measurement_units=(value)
         | 
| 13 | 
            +
                  unless PadesMeasurementUnits.contains?(value)
         | 
| 14 | 
            +
                    raise 'The provided "measurement_units" is not valid. Try using PadesMeasurementUnits constants'
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  @measurement_units = value
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def to_model
         | 
| 21 | 
            +
                  {
         | 
| 22 | 
            +
                      'pageNumber': @page_number,
         | 
| 23 | 
            +
                      'measurementUnits': @measurement_units,
         | 
| 24 | 
            +
                      'pageOptimization': @page_optimization&.to_model
         | 
| 25 | 
            +
                  }
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
              class PadesVisualRectangle
         | 
| 3 | 
            +
                attr_accessor :left, :top, :right, :bottom, :width, :height
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize
         | 
| 6 | 
            +
                  @left = nil
         | 
| 7 | 
            +
                  @top = nil
         | 
| 8 | 
            +
                  @right = nil
         | 
| 9 | 
            +
                  @bottom = nil
         | 
| 10 | 
            +
                  @width = nil
         | 
| 11 | 
            +
                  @height = nil
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def set_width_centered(width)
         | 
| 15 | 
            +
                  @width = width
         | 
| 16 | 
            +
                  @left = nil
         | 
| 17 | 
            +
                  @right = nil
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def set_width_left_anchored(width, left)
         | 
| 21 | 
            +
                  @width = width
         | 
| 22 | 
            +
                  @left = left
         | 
| 23 | 
            +
                  @right = nil
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def set_width_right_anchored(width, right)
         | 
| 27 | 
            +
                  @width = width
         | 
| 28 | 
            +
                  @left = nil
         | 
| 29 | 
            +
                  @right = right
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def set_horizontal_stretch(left, right)
         | 
| 33 | 
            +
                  @width = nil
         | 
| 34 | 
            +
                  @left = left
         | 
| 35 | 
            +
                  @right = right
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def set_height_centered(height)
         | 
| 39 | 
            +
                  @height = height
         | 
| 40 | 
            +
                  @top = nil
         | 
| 41 | 
            +
                  @bottom = nil
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def set_height_top_anchored(height, top)
         | 
| 45 | 
            +
                  @height = height
         | 
| 46 | 
            +
                  @top = top
         | 
| 47 | 
            +
                  @bottom = nil
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def set_height_bottom_anchored(height, bottom)
         | 
| 51 | 
            +
                  @height = height
         | 
| 52 | 
            +
                  @top = nil
         | 
| 53 | 
            +
                  @bottom = bottom
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def set_vertical_stretch(top, bottom)
         | 
| 57 | 
            +
                  @height = nil
         | 
| 58 | 
            +
                  @top = top
         | 
| 59 | 
            +
                  @bottom = bottom
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def to_model
         | 
| 63 | 
            +
                  {
         | 
| 64 | 
            +
                      left: @left,
         | 
| 65 | 
            +
                      top: @top,
         | 
| 66 | 
            +
                      right: @right,
         | 
| 67 | 
            +
                      bottom: @bottom,
         | 
| 68 | 
            +
                      width: @width,
         | 
| 69 | 
            +
                      height: @height,
         | 
| 70 | 
            +
                  }
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
              class PadesVisualRepresentation
         | 
| 3 | 
            +
                attr_accessor :text, :image, :position
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(text=nil, image=nil, position=nil)
         | 
| 6 | 
            +
                  @text = text
         | 
| 7 | 
            +
                  @image = image
         | 
| 8 | 
            +
                  @position = position
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def to_model
         | 
| 12 | 
            +
                  unless @position
         | 
| 13 | 
            +
                    raise new 'The visual representation position was not set'
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  {
         | 
| 16 | 
            +
                      position: @position&.to_model,
         | 
| 17 | 
            +
                      text: @text&.to_model,
         | 
| 18 | 
            +
                      image: @image&.to_model,
         | 
| 19 | 
            +
                  }
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
              class PadesVisualText
         | 
| 3 | 
            +
                attr_reader :horizontal_align
         | 
| 4 | 
            +
                attr_accessor :text, :include_signing_time, :font_size,
         | 
| 5 | 
            +
                              :container, :signing_time_format
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(text=nil, include_signing_time=nil, font_size=nil)
         | 
| 8 | 
            +
                  @horizontal_align = :left
         | 
| 9 | 
            +
                  @text = text
         | 
| 10 | 
            +
                  @include_signing_time = include_signing_time
         | 
| 11 | 
            +
                  @font_size = font_size
         | 
| 12 | 
            +
                  @container = nil
         | 
| 13 | 
            +
                  @signing_time_format = nil
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def horizontal_align=(value)
         | 
| 17 | 
            +
                  unless PadesTextHorizontalAlign.contains?(value)
         | 
| 18 | 
            +
                    raise 'The provided "horizontal_align" is not valid. Try using PadesTextHorizontalAlign constants'
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  @horizontal_align = value
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def to_model
         | 
| 25 | 
            +
                  {
         | 
| 26 | 
            +
                      'fontSize': @font_size,
         | 
| 27 | 
            +
                      'text': @text,
         | 
| 28 | 
            +
                      'includeSigningTime': @include_signing_time,
         | 
| 29 | 
            +
                      'signingTimeFormat': @signing_time_format,
         | 
| 30 | 
            +
                      'container': @container&.to_model,
         | 
| 31 | 
            +
                      'horizontalAlign': @horizontal_align
         | 
| 32 | 
            +
                  }
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class PKCertificate
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                attr_accessor :subject_name, :email_address, :issuer_name, :serial_number,
         | 
| 6 | 
            +
                              :validity_start, :validity_end, :pki_brazil, :pki_italy,
         | 
| 7 | 
            +
                              :issuer, :binary_thumbprint_sha256, :thumbprint
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(model)
         | 
| 10 | 
            +
                  @subject_name = nil
         | 
| 11 | 
            +
                  @email_address = nil
         | 
| 12 | 
            +
                  @issuer_name = nil
         | 
| 13 | 
            +
                  @serial_number = nil
         | 
| 14 | 
            +
                  @validity_start = nil
         | 
| 15 | 
            +
                  @validity_end = nil
         | 
| 16 | 
            +
                  @pki_brazil = nil
         | 
| 17 | 
            +
                  @pki_italy = nil
         | 
| 18 | 
            +
                  @issuer = nil
         | 
| 19 | 
            +
                  @binary_thumbprint_sha256 = nil
         | 
| 20 | 
            +
                  @thumbprint = nil
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  unless model.nil?
         | 
| 23 | 
            +
                    @email_address = model.fetch(:emailAddress)
         | 
| 24 | 
            +
                    @serial_number = model.fetch(:serialNumber)
         | 
| 25 | 
            +
                    @validity_start = model.fetch(:validityStart)
         | 
| 26 | 
            +
                    @validity_end = model.fetch(:validityEnd)
         | 
| 27 | 
            +
                    @thumbprint = model.fetch(:thumbprint)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    subject_name = model.fetch(:subjectName)
         | 
| 30 | 
            +
                    if subject_name
         | 
| 31 | 
            +
                      @subject_name = Name.new(subject_name)
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    issuer_name = model.fetch(:issuerName)
         | 
| 35 | 
            +
                    if issuer_name
         | 
| 36 | 
            +
                      @issuer_name = Name.new(issuer_name)
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    pki_brazil = model.fetch(:pkiBrazil)
         | 
| 40 | 
            +
                    if pki_brazil
         | 
| 41 | 
            +
                      @pki_brazil = PkiBrazilCertificateFields.new(pki_brazil)
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    pki_italy = model.fetch(:pkiItaly)
         | 
| 45 | 
            +
                    if pki_italy
         | 
| 46 | 
            +
                      @pki_italy = PkiItalyCertificateFields.new(pki_italy)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    issuer = model.fetch(:issuer)
         | 
| 50 | 
            +
                    if issuer
         | 
| 51 | 
            +
                      @issuer = PKCertificate.new(issuer)
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    binary_thumbprint_sha256 = model.fetch(:binaryThumbprintSHA256)
         | 
| 55 | 
            +
                    if binary_thumbprint_sha256
         | 
| 56 | 
            +
                      @binary_thumbprint_sha256 = Base64.decode64(binary_thumbprint_sha256)
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class PkiBrazilCertificateFields
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                attr_accessor :rg_emissor_uf, :cnpj, :rg_numero, :oab_numero, :company_name,
         | 
| 6 | 
            +
                              :rg_emissor, :certificate_type, :cpf, :responsavel,
         | 
| 7 | 
            +
                              :date_of_birth, :oab_uf
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(model)
         | 
| 10 | 
            +
                  @certificate_type = nil
         | 
| 11 | 
            +
                  @cpf = nil
         | 
| 12 | 
            +
                  @cnpj = nil
         | 
| 13 | 
            +
                  @responsavel = nil
         | 
| 14 | 
            +
                  @date_of_birth = nil
         | 
| 15 | 
            +
                  @company_name = nil
         | 
| 16 | 
            +
                  @rg_numero = nil
         | 
| 17 | 
            +
                  @rg_emissor = nil
         | 
| 18 | 
            +
                  @rg_emissor_uf = nil
         | 
| 19 | 
            +
                  @oab_numero = nil
         | 
| 20 | 
            +
                  @oab_uf = nil
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  unless model.nil?
         | 
| 23 | 
            +
                    @certificate_type = model.fetch(:certificateType)
         | 
| 24 | 
            +
                    @cpf = model.fetch(:cpf)
         | 
| 25 | 
            +
                    @cnpj = model.fetch(:cnpj)
         | 
| 26 | 
            +
                    @responsavel = model.fetch(:responsavel)
         | 
| 27 | 
            +
                    @date_of_birth = model.fetch(:dateOfBirth)
         | 
| 28 | 
            +
                    @company_name = model.fetch(:companyName)
         | 
| 29 | 
            +
                    @rg_numero = model.fetch(:rgNumero)
         | 
| 30 | 
            +
                    @rg_emissor = model.fetch(:rgEmissor)
         | 
| 31 | 
            +
                    @rg_emissor_uf = model.fetch(:rgEmissorUF)
         | 
| 32 | 
            +
                    @oab_numero = model.fetch(:oabNumero)
         | 
| 33 | 
            +
                    @oab_uf = model.fetch(:oabUF)
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def cpf_formatted
         | 
| 38 | 
            +
                  unless @cpf
         | 
| 39 | 
            +
                    return nil
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                  unless /^\d{11}$/.match(@cpf)
         | 
| 42 | 
            +
                    return @cpf
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                  "#{@cpf[0..2]}.#{@cpf[3..5]}.#{@cpf[6..8]}-#{@cpf[9..-1]}"
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def cnpj_formatted
         | 
| 48 | 
            +
                  unless @cnpj
         | 
| 49 | 
            +
                    return nil
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                  unless /^\d{14}$/.match(@cnpj)
         | 
| 52 | 
            +
                    return @cnpj
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                  "#{@cnpj[0..1]}.#{@cnpj[2..4]}.#{@cnpj[5..7]}/#{@cnpj[8..11]}-#{@cnpj[12..-1]}"
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
              class PkiBrazilCertificateTypes < Enum
         | 
| 3 | 
            +
                UNKNOWN = 'Unknown'
         | 
| 4 | 
            +
                A1 = 'A1'
         | 
| 5 | 
            +
                A2 = 'A2'
         | 
| 6 | 
            +
                A3 = 'A3'
         | 
| 7 | 
            +
                A4 = 'A4'
         | 
| 8 | 
            +
                S1 = 'S1'
         | 
| 9 | 
            +
                S2 = 'S2'
         | 
| 10 | 
            +
                S3 = 'S3'
         | 
| 11 | 
            +
                S4 = 'S4'
         | 
| 12 | 
            +
                T3 = 'T3'
         | 
| 13 | 
            +
                T4 = 'T4'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                VALUES = [
         | 
| 16 | 
            +
                    UNKNOWN, A1, A2, A3, A4, S1, S2, S3, S4, T3, T4
         | 
| 17 | 
            +
                ]
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module PkiExpress
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class PkiExpressConfig
         | 
| 4 | 
            +
                attr_accessor :pki_express_home, :temp_folder, :transfer_data_folder
         | 
| 5 | 
            +
                @@single_temp_folder = nil
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(pki_express_home = nil, temp_folder = nil, transfer_data_folder = nil)
         | 
| 8 | 
            +
                  if not temp_folder.nil? and Pathname.exist?(temp_folder)
         | 
| 9 | 
            +
                    @temp_folder = temp_folder
         | 
| 10 | 
            +
                  else
         | 
| 11 | 
            +
                    if @@single_temp_folder.nil?
         | 
| 12 | 
            +
                      @@single_temp_folder = Dir.mktmpdir('pkie')
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                    @temp_folder = @@single_temp_folder
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  if not transfer_data_folder.nil? and Pathname.exist?(transfer_data_folder)
         | 
| 18 | 
            +
                    @transfer_data_folder = transfer_data_folder
         | 
| 19 | 
            +
                  else
         | 
| 20 | 
            +
                    @transfer_data_folder = @temp_folder
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  @pki_express_home = pki_express_home
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,216 @@ | |
| 1 | 
            +
            require 'shellwords'
         | 
| 2 | 
            +
            require 'open3'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module PkiExpress
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class PkiExpressOperator
         | 
| 7 | 
            +
                attr_accessor :offline, :trust_lacuna_test_root, :signature_policy,
         | 
| 8 | 
            +
                              :timestamp_authority
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def initialize(config = PkiExpressConfig.new)
         | 
| 11 | 
            +
                  @temp_files = []
         | 
| 12 | 
            +
                  @file_references = {}
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  @config = config
         | 
| 15 | 
            +
                  @version_manager = VersionManager.new
         | 
| 16 | 
            +
                  @trusted_roots = []
         | 
| 17 | 
            +
                  @offline = false
         | 
| 18 | 
            +
                  @trust_lacuna_test_root = false
         | 
| 19 | 
            +
                  @signature_policy = nil
         | 
| 20 | 
            +
                  @timestamp_authority = nil
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  ObjectSpace.define_finalizer(self, self.class.method(:finalize))
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.finalize
         | 
| 26 | 
            +
                  @temp_files.each do |file|
         | 
| 27 | 
            +
                    File.delete(file) if File.exist?(file)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def add_file_reference(key, reference_path)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  if reference_path.nil?
         | 
| 34 | 
            +
                    raise ArgumentError.new('The provided reference path is not valid')
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  unless File.exists?(reference_path)
         | 
| 38 | 
            +
                    raise ArgumentError.new('The provided reference file was not found')
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  @file_references[key] = reference_path
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def add_trusted_root(root_path)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  if root_path.nil?
         | 
| 47 | 
            +
                    raise ArgumentError.new('The provided trusted root path is not valid')
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  unless File.exists?(root_path)
         | 
| 51 | 
            +
                    raise ArgumentError.new("The provided trusted root path doesn't exist: #{root_path}")
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  @trusted_roots.append(root_path)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                protected
         | 
| 58 | 
            +
                def invoke_plain(command, args = [])
         | 
| 59 | 
            +
                  invoke(command, args, true)
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def invoke(command, args = [], plain_output = false)
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  # Add PKI Express invocation arguments.
         | 
| 65 | 
            +
                  cmd_args = []
         | 
| 66 | 
            +
                  get_pki_express_invocation.each do |arg|
         | 
| 67 | 
            +
                    cmd_args.append(arg)
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  # Add PKI Express command.
         | 
| 71 | 
            +
                  cmd_args.append(command)
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  # Add PKI Express arguments.
         | 
| 74 | 
            +
                  cmd_args.concat args
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  # Add file references if added.
         | 
| 77 | 
            +
                  unless @file_references.nil?
         | 
| 78 | 
            +
                    @file_references.each do |key, value|
         | 
| 79 | 
            +
                      cmd_args.append('--file_reference')
         | 
| 80 | 
            +
                      cmd_args.append("#{key}=#{value}")
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  # Add trusted roots if added.
         | 
| 85 | 
            +
                  unless @trusted_roots.nil?
         | 
| 86 | 
            +
                    @trusted_roots.each do |trusted_root|
         | 
| 87 | 
            +
                      cmd_args.append('--trust-root')
         | 
| 88 | 
            +
                      cmd_args.append(trusted_root)
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  # Add trust Lacuna test root if set.
         | 
| 93 | 
            +
                  if @trust_lacuna_test_root
         | 
| 94 | 
            +
                    cmd_args.append('--trust-test')
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  # Add offline option if provided.
         | 
| 98 | 
            +
                  if @offline
         | 
| 99 | 
            +
                    cmd_args.append('--offline')
         | 
| 100 | 
            +
                    # This option can only be used on versions greater than 1.2 of the
         | 
| 101 | 
            +
                    # PKI Express.
         | 
| 102 | 
            +
                    @version_manager.require_version('1.2')
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  # Add base64 output option
         | 
| 106 | 
            +
                  unless plain_output
         | 
| 107 | 
            +
                    cmd_args.append('--base64')
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  # Verify the necessity of using the --min-version flag.
         | 
| 111 | 
            +
                  if @version_manager.require_min_version_flag?
         | 
| 112 | 
            +
                    cmd_args.append('--min-version')
         | 
| 113 | 
            +
                    cmd_args.append(@version_manager.min_version.to_s)
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  # Escape command args
         | 
| 117 | 
            +
                  escaped = []
         | 
| 118 | 
            +
                  cmd_args.each do |arg|
         | 
| 119 | 
            +
                    escaped.append("\"#{arg}\"")
         | 
| 120 | 
            +
                    # escaped.append(Shellwords.escape(arg))
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  # Perform the "dotnet" command.
         | 
| 124 | 
            +
                  stdout, _stderr, status = Open3.capture3(escaped.join(' '))
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                  if status != 0
         | 
| 127 | 
            +
                    if status === ErrorCodes::BAD_SYNTAX and @version_manager.min_version > '1.0'
         | 
| 128 | 
            +
                      raise CommandError.new(status, "#{stdout}  >>>>> TIP: This operation requires PKI Express #{@version_manager.min_version}, please check your PKI Express version.")
         | 
| 129 | 
            +
                    end
         | 
| 130 | 
            +
                    if status === ErrorCodes::VALIDATION_FAILED
         | 
| 131 | 
            +
                      raise ValidationError.new(stdout)
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
                    if status === ErrorCodes::COMMAND_NOT_FOUND
         | 
| 134 | 
            +
                      raise InstallationNotFoundError.new("Could not find PKI Express's installation.")
         | 
| 135 | 
            +
                    end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    raise CommandError.new(status, stdout)
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                  # Return stdout if the command executed with success.
         | 
| 141 | 
            +
                  stdout
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                def get_pki_express_invocation
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                  # Identify OS.
         | 
| 147 | 
            +
                  if (/linux/ =~ RUBY_PLATFORM) != nil
         | 
| 148 | 
            +
                    system = :linux
         | 
| 149 | 
            +
                  elsif (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
         | 
| 150 | 
            +
                    system = :win
         | 
| 151 | 
            +
                  else
         | 
| 152 | 
            +
                    raise Error.new("Unsupported OS: #{RUBY_PLATFORM}")
         | 
| 153 | 
            +
                  end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                  # Verify if hte PKI Express home is set on configuration
         | 
| 156 | 
            +
                  home = @config.pki_express_home
         | 
| 157 | 
            +
                  if not home.nil?
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                    if system == :linux
         | 
| 160 | 
            +
                      unless File.exists?(File.expand_path('pkie.dll', home))
         | 
| 161 | 
            +
                        raise InstallationNotFoundError.new("The file pkie.dll could not be found on directory #{home}")
         | 
| 162 | 
            +
                      end
         | 
| 163 | 
            +
                    elsif not File.exists?(File.expand_path('pkie.exe', home))
         | 
| 164 | 
            +
                      raise InstallationNotFoundError.new("The file pkie.exe could not be found on directory #{home}")
         | 
| 165 | 
            +
                    end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                  elsif system == :win
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                    if File.exists?(File.join(ENV['ProgramW6432'], 'Lacuna Software', 'PKI Express', 'pkie.exe'))
         | 
| 170 | 
            +
                      home = File.join(ENV['ProgramW6432'], 'Lacuna Software', 'PKI Express')
         | 
| 171 | 
            +
                    elsif File.exists?(File.join(ENV['ProgramFiles(x86)'], 'Lacuna Software', 'PKI Express', 'pkie.exe'))
         | 
| 172 | 
            +
                      home = File.join(ENV['ProgramFiles(x86)'], 'Lacuna Software', 'PKI Express')
         | 
| 173 | 
            +
                    elsif File.exists?(File.join(ENV['LOCALAPPDATA'], 'Lacuna Software', 'PKI Express', 'pkie.exe'))
         | 
| 174 | 
            +
                      home = File.join(ENV['LOCALAPPDATA'], 'Lacuna Software', 'PKI Express')
         | 
| 175 | 
            +
                    elsif File.exists?(File.join(ENV['LOCALAPPDATA'], 'Lacuna Software (x86)', 'PKI Express', 'pkie.exe'))
         | 
| 176 | 
            +
                      home = File.join(ENV['LOCALAPPDATA'], 'Lacuna Software (x86)', 'PKI Express')
         | 
| 177 | 
            +
                    end
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                    if home.nil?
         | 
| 180 | 
            +
                      raise InstallationNotFoundError.new('Could not determine the
         | 
| 181 | 
            +
                        installation folder of PKI Express. If you installed PKI Express on
         | 
| 182 | 
            +
                        a custom folder, make sure your chosen folder are specified on the
         | 
| 183 | 
            +
                        PkiExpressConfig object.')
         | 
| 184 | 
            +
                    end
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                  if system == :linux
         | 
| 188 | 
            +
                    unless home.nil?
         | 
| 189 | 
            +
                      return ['dotnet', File.expand_path('pkie.dll', home)]
         | 
| 190 | 
            +
                    end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                    return ['pkie']
         | 
| 193 | 
            +
                  end
         | 
| 194 | 
            +
                  [File.expand_path('pkie.exe', home)]
         | 
| 195 | 
            +
                end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                def parse_output(data_base64)
         | 
| 198 | 
            +
                  json_buff = Base64.decode64(data_base64)
         | 
| 199 | 
            +
                  JSON.parse(json_buff, symbolize_names: true)
         | 
| 200 | 
            +
                end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                def create_temp_file
         | 
| 203 | 
            +
                  file = Tempfile.new('pkie', @config.temp_folder)
         | 
| 204 | 
            +
                  temp_path = file.path
         | 
| 205 | 
            +
                  file.close
         | 
| 206 | 
            +
                  @temp_files.append(temp_path)
         | 
| 207 | 
            +
                  temp_path
         | 
| 208 | 
            +
                end
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                def get_transfer_filename
         | 
| 211 | 
            +
                  # Generate 16 random bytes. Return a string containing the hex decimals of
         | 
| 212 | 
            +
                  # this array.
         | 
| 213 | 
            +
                  SecureRandom.hex(16)
         | 
| 214 | 
            +
                end
         | 
| 215 | 
            +
              end
         | 
| 216 | 
            +
            end
         |