Class: Jodid::Keychain

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/jodid/keychain.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &key_not_found) ⇒ Keychain

Returns a new instance of Keychain.


12
13
14
15
16
17
# File 'lib/jodid/keychain.rb', line 12

def initialize(options = {}, &key_not_found)
  @storage = options.fetch(:storage) do
    require_relative 'storage/in_mem_store'
    Storage::InMemStore.new(options, &key_not_found)
  end
end

Instance Attribute Details

#storageObject (readonly)

Returns the value of attribute storage


8
9
10
# File 'lib/jodid/keychain.rb', line 8

def storage
  @storage
end

Instance Method Details

#auth(identity, password) ⇒ Object


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/jodid/keychain.rb', line 19

def auth(identity, password)
  salt = Crypto::PwHash::ScryptSalsa208SHA256.salt
  key = Crypto::PwHash::ScryptSalsa208SHA256.scryptsalsa208sha256(
    Crypto::AEAD::Chacha20Poly1305::KEYBYTES, password, salt)
  nonce = Crypto::AEAD::Chacha20Poly1305.nonce
  seed = RandomBytes.buf(Crypto::Sign::SEEDBYTES)
  ciphertext = Crypto::AEAD::Chacha20Poly1305.encrypt(seed,
    identity, nonce, key)
  pk, sk = Crypto::Sign.memory_locked_seed_keypair(seed)
  Sodium.memzero(seed, Crypto::Sign::SEEDBYTES)
  @storage.store(identity, :salt, salt)
  @storage.store(identity, :nonce, nonce)
  @storage.store(identity, :ciphertext, ciphertext)
  store_public_key(identity, pk)
  Base64.strict_encode64(pk)
ensure
  Sodium.memzero(password, password.bytesize)
  password.clear
end

#store_public_key(identity, public_key) ⇒ Object


54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/jodid/keychain.rb', line 54

def store_public_key(identity, public_key)
  case public_key.bytesize
  when 64 # hex
    @storage.store_public_key(identity, Sodium::Utils.hex2bin(public_key))
  when 44 # base64
    @storage.store_public_key(identity, Base64.strict_decode64(public_key))
  when 32 # raw
    @storage.store_public_key(identity, public_key)
  else
    fail Sodium::LengthError, "public_key is not in hex, base64 or raw encoding", caller
  end
end

#verify(identity, password) ⇒ Object


39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/jodid/keychain.rb', line 39

def verify(identity, password)
  key = Crypto::PwHash::ScryptSalsa208SHA256.scryptsalsa208sha256(
    Crypto::AEAD::Chacha20Poly1305::KEYBYTES, password,
    @storage.fetch(identity, :salt))
  seed = Crypto::AEAD::Chacha20Poly1305.decrypt(
    @storage.fetch(identity, :ciphertext),
    identity, @storage.fetch(identity, :nonce), key)
  cryptor = Cryptor.new(*Crypto::Sign.memory_locked_seed_keypair(seed), self)
  Sodium.memzero(seed, Crypto::Sign::SEEDBYTES)
  cryptor
ensure
  Sodium.memzero(password, password.bytesize)
  password.clear
end