Class: Sphragis::Providers::FortifyWebcryptoProvider

Inherits:
BaseProvider
  • Object
show all
Defined in:
lib/sphragis/providers/fortify_webcrypto_provider.rb

Overview

Fortify by Peculiar Ventures Provider Uses Fortify WebCrypto bridge to access hardware tokens

Requirements:

License: MIT (FREE for all use)

Constant Summary collapse

FORTIFY_DEFAULT_URL =
"https://localhost:31337"

Instance Attribute Summary

Attributes inherited from BaseProvider

#config

Instance Method Summary collapse

Methods inherited from BaseProvider

#connected?, #provider_name

Constructor Details

#initialize(config = {}) ⇒ FortifyWebcryptoProvider

Initialize Fortify WebCrypto provider

Parameters:

  • config (Hash) (defaults to: {})

    Configuration options

    • api_url: Fortify API URL (default: localhost:31337)

    • token_pin: Hardware token PIN

    • certificate_id: Certificate identifier on token

    • verify_ssl: Verify SSL (default: false for localhost)



31
32
33
34
35
36
37
38
39
40
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 31

def initialize(config = {})
  super
  @config = {
    api_url: config[:api_url] || FORTIFY_DEFAULT_URL,
    token_pin: config[:token_pin],
    certificate_id: config[:certificate_id],
    verify_ssl: config[:verify_ssl] || false
  }
  @http = setup_http_client
end

Instance Method Details

#certificateObject

Raises:



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

def certificate
  raise ProviderError, "Not connected to Fortify" unless connected?

  cert_id = @config[:certificate_id] || find_signing_certificate
  cert_info = get_certificate_info(cert_id)

  {
    provider: "fortify_webcrypto",
    subject: cert_info[:subject],
    issuer: cert_info[:issuer],
    serial: cert_info[:serial],
    not_before: cert_info[:not_before],
    not_after: cert_info[:not_after],
    key_usage: cert_info[:key_usage],
    hardware_backed: true
  }
end

#connectObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 42

def connect
  validate_configuration!

  # Check if Fortify is running
  unless fortify_running?
    raise ProviderError, "Fortify app is not running. Start it with: fortify"
  end

  # List available providers (tokens)
  providers = list_providers

  if providers.empty?
    raise ProviderError, "No hardware tokens detected. Please insert your token."
  end

  # Get the first available provider
  @provider_id = providers.first["id"]

  # Login to token with PIN
  (@provider_id, @config[:token_pin])

  @session = {
    connected: true,
    provider: "fortify_webcrypto",
    provider_id: @provider_id,
    fortify_url: @config[:api_url]
  }
  true
rescue StandardError => e
  raise ProviderError, "Failed to connect to Fortify: #{e.message}"
end

#disconnectObject



74
75
76
77
78
79
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 74

def disconnect
  # Logout from token
  logout(@session[:provider_id]) if @session
  @session = nil
  true
end

#fortify_infoHash

Get Fortify version info

Returns:

  • (Hash)


135
136
137
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 135

def fortify_info
  make_request(:get, "/info")
end

#fortify_running?Boolean

Check if Fortify app is running

Returns:

  • (Boolean)


126
127
128
129
130
131
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 126

def fortify_running?
  response = make_request(:get, "/info")
  response.is_a?(Hash) && response["name"] == "fortify"
rescue StandardError
  false
end

#sign(data) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 81

def sign(data)
  raise ProviderError, "Not connected to Fortify" unless connected?

  # Get certificate from token
  cert_id = @config[:certificate_id] || find_signing_certificate

  # Sign data using WebCrypto API
  signature_result = sign_with_webcrypto(cert_id, data)

  {
    provider: "fortify_webcrypto",
    algorithm: signature_result[:algorithm],
    signature: signature_result[:signature],
    timestamp: Time.now.utc.iso8601,
    certificate_id: cert_id,
    hardware_token: true
  }
rescue StandardError => e
  raise ProviderError, "Failed to sign with Fortify: #{e.message}"
end

#validate_configuration!Object

Raises:



120
121
122
# File 'lib/sphragis/providers/fortify_webcrypto_provider.rb', line 120

def validate_configuration!
  raise ProviderError, "Token PIN not configured" if @config[:token_pin].nil?
end