Module: Robocap::SDK::Ownership

Defined in:
lib/robocap/sdk/ownership.rb

Class Method Summary collapse

Class Method Details

.spki_fingerprint(public_key) ⇒ Object



16
17
18
19
# File 'lib/robocap/sdk/ownership.rb', line 16

def spki_fingerprint(public_key)
  der = public_key.public_to_der
  Digest::SHA256.hexdigest(der)
end

.verify(customer_id:, user_private_pem:, key_vault: nil, sdk_root: nil) ⇒ Object

Raises:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
# File 'lib/robocap/sdk/ownership.rb', line 21

def verify(customer_id:, user_private_pem:, key_vault: nil, sdk_root: nil)
  vault = key_vault || KeyVault.new(sdk_root || Config.default_sdk_root)

  unless vault.exists_customer?(customer_id)
    raise Error.new(
      code: ErrorCode::ERR_CUSTOMER_NOT_FOUND,
      message: "Customer #{customer_id} not found in key vault",
    )
  end

  priv = begin
    OpenSSL::PKey::RSA.new(user_private_pem)
  rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::PKeyError => exc
    raise Error.new(
      code: ErrorCode::ERR_KEY_OWNERSHIP_FAILED,
      message: 'Failed to parse user private key',
      detail: { reason: exc.message },
    )
  end

  unless priv.private?
    raise Error.new(
      code: ErrorCode::ERR_KEY_OWNERSHIP_FAILED,
      message: 'User key is not an RSA private key',
    )
  end

  user_fp = spki_fingerprint(priv.public_key)

  vault.list_rsa_versions(customer_id).each do |version|
    archived = vault.get_public_key(customer_id, version)
    archived_fp = spki_fingerprint(archived)
    if archived_fp == user_fp
      return VerifiedKeyVersion.new(
        customer_id: customer_id,
        matched_rsa_key_version: version,
        public_fingerprint: user_fp,
      )
    end
  end

  raise Error.new(
    code: ErrorCode::ERR_KEY_OWNERSHIP_FAILED,
    message: "User private key does not match any archived key for #{customer_id}",
  )
end