Giter Site home page Giter Site logo

raku-gpgme's Introduction

Raku GPGME - GNU Privacy Guard (GPG) Made Easy

Introduction

From the GPGME Manual:

‘GnuPG Made Easy’ (GPGME) is a C language library that allows to
add support for cryptography to a program. It is designed to make
access to public key crypto engines like GnuPG or GpgSM easier for
applications. GPGME provides a high-level crypto API for
encryption, decryption, signing, signature verification and key
management.

GPGME uses GnuPG and GpgSM as its backends to support OpenPGP and
the Cryptographic Message Syntax (CMS).

So essentially, this is a Raku Module interfacing with a C library interfacing with GnuPG and GpgSM command line programs.

Understanding how this module works will benefit from an understanding of the Gnu Privacy Guard and GnuPG Made Easy (GPGME).

Note, this is still a work in progress, more features may or may not be forthcoming!! Patches welcome!!

Basic Usage

use GPGME;
my $gpg = GPGME.new(:armor);                     # ASCII armor for key export
$gpg.create-key('[email protected]');                  # Add key to key ring
my $joes-key = $gpg.get-key('[email protected]');      # Retrieve a key
put $joes-key;                                   # Stringify key summary
put my $key = $gpg.export('[email protected]');        # Export from key ring
$gpg.import($key);                               # Import key

my $cipher = $gpg.encrypt('message', '[email protected]');

my $plain = $gpg.decrypt($cipher);

$gpg.signers('[email protected]');
my $signed = $gpg.sign('My message');

Functionality

Basic

use GPGME;
put GPGME.version;
put GPGME.dirinfo('gpg-name');
GPGME.set-locale('C');

GPGME Object and Context

The main GPGME object holds a context with various settings, and can be used to perform various functions.

use GPGME;
my $gpg = GPGME.new;
my $gpg = GPGME.new(:armor, :homedir</tmp/dir>);

See GPGME for more information.

Results

After performing an operation, the result of the operation can be retrieved from the context with the C method. As a convenience, most methods from the result objects are passed through to the result object.

For example, after a key generation operation, the CGPGME::GenKeyResult object can be retrieved with the C method. One of the attributes of that object is the fingerprint of the generated key, which can be retrieved with its C method.

$gpg.create-key('[email protected]');
my $result = $gpg.result;
my $fpr = $result.fpr;

This does the same thing, passing the I from the context to the result:

my $fpr = $gpg.fpr;

Of course, for key generation, the result object is returned from the I operation, so you can also just do:

my $fpr = $gpg.create-key('[email protected]').fpr;

You can additionally retrieve the result object immediately following the appropriate operation with these methods:

$gpg.genkey-result
$gpg.import-result
$gpg.sign-result
$gpg.encrypt-result
$gpg.decrypt-result
$gpg.verify-result

These are sometimes needed when an operation performs two actions (e.g. decrypt and verify).

These are only valid immediately following the appropriate operation, and all results must be used or copied prior to the next operation, when the results are no longer available.

Engine Information

.put for GPGME.engine-info;
GPGME.engine-info('openpgp', :homedir</tmp/dir>);

See GPGME::EngineInfo for more information.

Data Objects

A lot of data has to be exchanged between the user and the crypto engine, like plaintext messages, ciphertext, signatures and information about the keys. The technical details about exchanging the data information are completely abstracted by GPGME. The user provides and receives the data via GPGME::Data objects, regardless of the communication protocol between GPGME and the crypto engine in use.

In general the API will construct the appropriate GPGME::Data object for you.

For input objects, you can provide one of these types:

  • Blob -- Actual data to use
  • Str -- Actual data to use
  • IO::Path -- Filename of file to use
  • IO::Handle -- File with a native-descriptor to read from

For output objects, you can provide one of these types:

  • Str -- Filename of file to write to
  • IO::Path -- Filename to write to
  • IO::Handle -- File with a C to write to

When an output object is omitted, a memory buffer will be used and returned.

When a GPGME::Data object is returned, you can stringify it if and only if the data are utf8 encoded or ascii (usually produced when the :armor option was specified during context creation).

The object can also be treated as an IO::Handle and read from as usual.

Key Management

An important fact to remember is that in addition to providing mechanisms to manipulate keys, GPG also serves as a Key Store or 'Key Ring'. Keys can generally be referred to by patterns and fingerprints that map to actual keys stored in the key store.

Key Generation

GPGME Supports two different interfaces to Key Generation -- create-key and genkey.

$gpg.create-key('[email protected]');
my $key = $gpg.get-key('[email protected]');
$gpg.create-subkey($key);
$gpg.adduid($key, '[email protected]');
$gpg.set-uid-flag($key, '[email protected]');  # Make new one primary
$gpg.revuid($key, '[email protected]');                  # Revoke a user ID

genkey takes a set of parameters, expressed either as a single string, or a set of named parameters:

$gpg.genkey(q:to/END/)
Key-Type: default
Name-Email: [email protected]
END

or

$gpg.genkey(:Name-Email<[email protected]>);  # Key-Type defaults to 'default'

See GPG Key Generation and CSR and Certificate Creation for information on all the parameters.

Listing Keys

List keys in the key ring by specifying a list of patterns and optionally specifying the :secret option to retrieve secret keys.

$key = $gpg.get-key('[email protected]');
$key = $gpg.get-key($fpr, :secret);
.put for $gpg.keylist('[email protected]', :secret);
.put for $gpg.keylist(<alice harry bob>);

Individual attributes from the keys can be queried. See GPGME::Key for more information.

Deleting Keys

$gpg.delete-key($key, :secret, :force);
  • :secret deletes secret keys
  • :force overrides a user confirmation, but is only available after version 1.8.

Signing Keys

Key signatures are a unique concept of the OpenPGP protocol. They can be used to certify the validity of a key and are used to create the Web-of-Trust (WoT).

$gpg.signers('[email protected]');                     # select signers
$gpg.keysign($key);                                # Default sign all user IDs
$gpg.keysign($key, '[email protected]');                 # Specify a user ID
$gpg.keysign($key, :local);                        # Non exportable
$gpg.keysign($key, '[email protected]', expires => $DateTime);

Exporting Keys

my $gpg = GPGME.new(:armor);                   # Use :armor to get ASCII export
put $gpg.export('[email protected]');                # Stringify and print out
$gpg.export('[email protected]', :out<outputfile>);  # Export to filename
$gpg.export('[email protected]', out => $*OUT);      # Send to a file handle

Importing Keys

$gpg.import($someexportedkeydata);

Stores the ImportResult.

Encrypting a Plaintext

$cipher = $gpg.encrypt("my message", $key);             # Encrypt for a key
$cipher = $gpg.encrypt("my message", '[email protected]');     # Encrypt for a pattern
$cipher = $gpg.encrypt("my message", '[email protected]', :sign);  # Encrypt and sign

Stores the EncryptResult.

If signed as well with the :sign option, SignResult can be examined as well.

Decrypting

$plain = $gpg.decrypt($cipher);
$gpg.decrypt($cipher, out => 'filename');
$gpg.decrypt($cipher, out => $*OUT);
$gpg.decrypt($cipher, :verify);

Stores the DecryptResult.

If the signature was verified with the :verify option, the VerifyResult is also available.

Signing

A signature can contain signatures by one or more keys. The set of keys used to create a signatures is contained in a context, and is applied to all following signing operations in this context (until the set is changed).

They can be set either at GPGME creation with the :signers object, or with the .signers method later.

$gpg.signers('[email protected]');
my $signed = $gpg.sign('My message');
$gpg.sign($*IN, out => $*OUT);

my $signature = $gpg.sign('My message', :detach); # Detached signature

The SignResult will be available after signing.

Verifying Signature

$message = $gpg.verify($signed);
$gpg.verify('infile'.IO, :out<somefile>);

put $gpg.verify($signature, $message).status;      # Detached signature

The VerifyResult will be available after verification.

Entropy

Some GPGME actions (particularly key generation with very long keys) rely on the OS ability to generate a great deal of entropy. Things may appear to hang on entropy starved hosts. Tools like haveged can help the OS capture entropy. Even doing something simple like running sudo dd if=/dev/sda of=/dev/zero in the background can help speed things up.

INSTALL

You must install libgpgme which usually has the right dependencies on GPG as well.

  • For debian or ubuntu: apt install libgpgme11
  • For alpine: apk add gpgme
  • For CentOS: yum install gpgme

If you get locale errors on CentOS, you may need to run this:

yum install glibc-locale-source glibc-langpack-en
localedef -i en_US -f UTF-8 en_US.UTF-8

License

This work is subject to the Artistic License 2.0.

See LICENSE for more information.

raku-gpgme's People

Contributors

curttilmes avatar melezhik avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

melezhik

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.