Class: Saro::Dat::DatManager

Inherits:
Object
  • Object
show all
Defined in:
lib/saro/dat/dat_manager.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDatManager

Returns a new instance of DatManager.



13
14
15
16
17
# File 'lib/saro/dat/dat_manager.rb', line 13

def initialize
  @issuer = nil
  @certificates = []
  @lock = Concurrent::ReadWriteLock.new
end

Class Method Details

._issue(cert, plain, secure) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/saro/dat/dat_manager.rb', line 83

def self._issue(cert, plain, secure)
  now = Time.now.to_i
  expire = now + cert.dat_ttl
  cid_hex = cert.cid.to_s(16)

  plain_bytes = plain.is_a?(String) ? plain.encode('utf-8') : (plain || "".b)
  plain_b64 = Saro::Dat::Util.encode_base64_url_str(plain_bytes)

  encrypted_secure = cert.crypto_key.encrypt(secure)
  secure_b64 = Saro::Dat::Util.encode_base64_url_str(encrypted_secure)

  body = "#{expire}.#{cid_hex}.#{plain_b64}.#{secure_b64}"
  signature = Saro::Dat::Util.encode_base64_url_str(cert.signature_key.sign(body))

  "#{body}.#{signature}"
end

._parse(cert, dat_input) ⇒ Object

Raises:

  • (RuntimeError)


100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/saro/dat/dat_manager.rb', line 100

def self._parse(cert, dat_input)
  dat = Saro::Dat::Dat.from_value(dat_input)
  raise RuntimeError, "Invalid DAT: Format" unless dat.format
  raise RuntimeError, "Invalid DAT: Expired" if dat.expired?

  unless cert.signature_key.verify(dat.body_string, dat.signature)
    raise RuntimeError, "Invalid DAT: Signature"
  end

  decrypted_secure = cert.crypto_key.decrypt(dat.secure)
  Saro::Dat::DatPayload.new(dat.plain, decrypted_secure)
end

Instance Method Details

#exports(option) ⇒ Object



55
56
57
58
59
# File 'lib/saro/dat/dat_manager.rb', line 55

def exports(option)
  @lock.with_read_lock do
    @certificates.map { |cert| cert.exports(option) }.join("\n")
  end
end

#import_certificates(input_certs, clear: false) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/saro/dat/dat_manager.rb', line 19

def import_certificates(input_certs, clear: false)
  @lock.with_write_lock do
    certificates = clear ? [] : @certificates.dup
    
    before_cids = Set.new(certificates.map(&:cid))
    seen_cids = Set.new

    input_certs.each do |cert|
      raise ArgumentError, "Duplicate CID: #{cert.cid}" if seen_cids.include?(cert.cid)
      seen_cids.add(cert.cid)
      next if cert.expired?
      next if before_cids.include?(cert.cid)
      
      certificates << cert
    end

    certificates.sort_by!(&:dat_issue_end)
    
    # Find latest issuable certificate as issuer
    issuer = certificates.reverse_each.find(&:issuable?)

    @issuer = issuer
    @certificates = certificates
  end
end

#imports(format_str, clear: false) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/saro/dat/dat_manager.rb', line 45

def imports(format_str, clear: false)
  certs = []
  format_str.strip.split("\n").each do |line|
    line = line.strip
    next if line.empty?
    certs << Saro::Dat::DatCertificate.imports(line)
  end
  import_certificates(certs, clear: clear)
end

#issue(plain, secure) ⇒ Object

Raises:

  • (RuntimeError)


61
62
63
64
65
66
# File 'lib/saro/dat/dat_manager.rb', line 61

def issue(plain, secure)
  issuer = @lock.with_read_lock { @issuer }
  raise RuntimeError, "Invalid DAT: Signing Key Does Not Exist" unless issuer
  
  self.class._issue(issuer, plain, secure)
end

#parse(dat_input) ⇒ Object

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/saro/dat/dat_manager.rb', line 68

def parse(dat_input)
  dat = Saro::Dat::Dat.from_value(dat_input)
  raise ArgumentError, "Invalid DAT: Format" unless dat.format

  certificate = @lock.with_read_lock do
    @certificates.find { |c| c.cid == dat.cid }
  end
  
  raise ArgumentError, "Invalid DAT: CID(Certificate ID) Not Found" unless certificate
  
  self.class._parse(certificate, dat)
end