Ravn::

Crypto module

A module containing Ravn libsodium utility methods.

Constants

BUFSIZE

File encryption is broken into chunks to conserve memory. This is the maximum buffer size. It should not be altered without serious consideration - past files won’t be readable.

HEADERSIZE

The additional overhead for any encrypted ciphertext. (24 byte nonce plus a 16 byte authenticator).

Public Class Methods

reset()

Reset memoized values; primarily for testing.

# File lib/ravn/crypto.rb, line 36
def self::reset
        @secret_key = nil
end

Public Instance Methods

cryptobox( public_key=nil )

Create and return a new secret box with the private key.

# File lib/ravn/crypto.rb, line 103
def cryptobox( public_key=nil )
        if public_key
                return RbNaCl::SimpleBox.from_keypair( public_key, Ravn::Crypto.key )
        else
                return RbNaCl::SimpleBox.from_secret_key( Ravn::Crypto.key )
        end
end
decrypt( bytes, public_key=nil )

Decrypt bytes binary ciphertext, returning the original message. If a public_key is given, decrypt the message from the key’s owner.

# File lib/ravn/crypto.rb, line 55
def decrypt( bytes, public_key=nil )
        return Ravn::Crypto.cryptobox( public_key ).decrypt( bytes )
end
decrypt_file( input, output )

Decrypt an input file of arbitrary size in a memory efficient fashion, writing it to output. This expects 40 byte nonce and authenticator data for each BUFSIZE iteration. input and output must be Pathname objects - the output will be overwritten.

# File lib/ravn/crypto.rb, line 86
def decrypt_file( input, output )
        in_fh  = input.open( 'rb' )
        out_fh = output.open( 'wb' )
        buf    = String.new

        until in_fh.eof?
                break unless in_fh.read( BUFSIZE + HEADERSIZE, buf )
                out_fh.write Ravn::Crypto.decrypt( buf )
        end

ensure
        in_fh.close
        out_fh.close
end
encrypt( message, public_key=nil )

Encrypt and return a simple message string as binary ciphertext. If a public_key is given, encrypt the message for that instead of the local key.

# File lib/ravn/crypto.rb, line 48
def encrypt( message, public_key=nil )
        return Ravn::Crypto.cryptobox( public_key ).encrypt( message )
end
encrypt_file( input, output )

Encrypt an input file of arbitrary size in a memory efficient fashion, writing it to output stream. This writes a 40 byte nonce and authenticator data for each BUFSIZE iteration. input and output must be Pathname objects - the output will be overwritten.

# File lib/ravn/crypto.rb, line 65
def encrypt_file( input, output )
        in_fh  = input.open( 'rb' )
        out_fh = output.open( 'wb' )
        buf    = String.new

        until in_fh.eof?
                break unless in_fh.read( BUFSIZE, buf )
                out_fh.write Ravn::Crypto.encrypt( buf )
        end

ensure
        in_fh.close
        out_fh.close
end
key()

Return an instantiated RbNaCl::PrivateKey object read from disk. If a keyfile does not exist, generate a new one - this is primarily for development usage.

The key is stored in Base64 for easy visual comparison, and to mimic Wireguard display for private keys.

# File lib/ravn/crypto.rb, line 118
def key
        return @secret_key ||= begin
                keyfile = Ravn::Crypto.keyfile.expand_path

                if keyfile.exist?
                        RbNaCl::PrivateKey.new( keyfile.read.chomp.unpack1('m0') )
                else
                        key = RbNaCl::PrivateKey.generate

                        mode = File::WRONLY|File::EXCL|File::CREAT
                        keyfile.open( mode, 0400, encoding: 'us-ascii' ) do |keyfile|
                                keyfile.print [ key.to_s ].pack( 'm0' )
                        end
                        keyfile.chmod( 0400 )

                        raise SecurityError, "keyfile must not be world-readable" if keyfile.world_readable?
                        raise SecurityError, "keyfile must not be writable" if keyfile.writable?

                        key
                end
        end
end
public_key()

Return the RBNaCl::PublicKey side of the current key.

# File lib/ravn/crypto.rb, line 143
def public_key
        return Ravn::Crypto.key.public_key
end