# NAME

Crypt::ZCert - Manage ZeroMQ 4+ ZCert CURVE keys and certificates

# SYNOPSIS

    use Crypt::ZCert;

    my $zcert = Crypt::ZCert->new(
      public_file => "/foo/mycert",
      # Optionally specify a secret file;
      # defaults to "${public_file}_secret":
      secret_file => "/foo/sekrit",
    );

    # Loaded from existing 'secret_file' if present,
    # generated via libzmq's zmq_curve_keypair(3) if not:
    my $pubkey = $zcert->public_key;
    my $seckey = $zcert->secret_key;

    # ... or as the original Z85:
    my $pub_z85 = $zcert->public_key_z85;
    my $sec_z85 = $zcert->secret_key_z85;

    # Alter metadata:
    $zcert->metadata->set(foo => 'bar');

    # Commit certificate to disk
    # (as '/foo/mycert', '/foo/mycert_secret' pair)
    # Without '->new(adjust_permissions => 0)', _secret becomes chmod 0600:
    $zcert->commit;

    # Retrieve a public/secret ZCert file pair (as ZPL) without writing:
    my $certdata = $zcert->export_zcert;
    my $pubdata  = $certdata->public;
    my $secdata  = $certdata->secret;

    # Retrieve a newly-generated key pair (no certificate):
    my $keypair = Crypt::ZCert->new->generate_keypair;
    my $pub_z85 = $keypair->public;
    my $sec_z85 = $keypair->secret;

# DESCRIPTION

A module for managing ZeroMQ "ZCert" certificates and calling
[zmq\_curve\_keypair(3)](http://man.he.net/man3/zmq_curve_keypair) from [libzmq](http://www.zeromq.org) to generate CURVE
keys.

## ZCerts

ZCert files are `ZPL` format (see [Text::ZPL](https://metacpan.org/pod/Text::ZPL)) with two subsections,
`curve` and `metadata`. The `curve` section specifies `public-key` and
`secret-key` names whose values are `Z85`-encoded (see [Convert::Z85](https://metacpan.org/pod/Convert::Z85)) CURVE
keys.

On disk, the certificate is stored as two files; a ["public\_file"](#public_file) (containing
only the public key) and a ["secret\_file"](#secret_file) (containing both keys).

Also see: [http://czmq.zeromq.org/manual:zcert](http://czmq.zeromq.org/manual:zcert)

## ATTRIBUTES

### public\_file

The path to the public ZCert.

Coerced to a [Path::Tiny](https://metacpan.org/pod/Path::Tiny).

Predicate: `has_public_file`

### secret\_file

The path to the secret ZCert; defaults to appending '\_secret' to
["public\_file"](#public_file).

Coerced to a [Path::Tiny](https://metacpan.org/pod/Path::Tiny).

Predicate: `has_secret_file`

### adjust\_permissions

If boolean true, `chmod` will be used to attempt to set the ["secret\_file"](#secret_file)'s
permissions to `0600` after writing.

### ignore\_existing

If boolean true, any existing ["public\_file"](#public_file) / ["secret\_file"](#secret_file) will not be
read; calling a ["commit"](#commit) will cause a forcible key regeneration and rewrite
of the existing certificate files.

(Obviously, this should be used with caution.)

### public\_key

The public key, as a binary string.

If none is specified at construction-time and no ["secret\_file"](#secret_file) exists, a new
key pair is generated via [zmq\_curve\_keypair(3)](http://man.he.net/man3/zmq_curve_keypair) and ["secret\_key"](#secret_key) is set
appropriately.

### secret\_key

The secret key, as a binary string.

If none is specified at construction-time and no ["secret\_file"](#secret_file) exists, a new
key pair is generated via [zmq\_curve\_keypair(3)](http://man.he.net/man3/zmq_curve_keypair) and ["public\_key"](#public_key) is set
appropriately.

### public\_key\_z85

The ["public\_key"](#public_key), as a `Z85`-encoded ASCII string (see [Convert::Z85](https://metacpan.org/pod/Convert::Z85)).

### secret\_key\_z85

The ["secret\_key"](#secret_key), as a `Z85`-encoded ASCII string (see [Convert::Z85](https://metacpan.org/pod/Convert::Z85)).

### metadata

    # Get value:
    my $foo = $zcert->metadata->get('foo');

    # Iterate over metadata:
    my $iter = $zcert->metadata->iter;
    while ( my ($key, $val) = $iter->() ) {
      print "$key -> $val\n";
    }

    # Update metadata & write to disk:
    $zcert->metadata->set(foo => 'bar');
    $zcert->commit;

The certificate metadata, as a [List::Objects::WithUtils::Hash](https://metacpan.org/pod/List::Objects::WithUtils::Hash).

If the object is constructed from an existing ["public\_file"](#public_file) /
["secret\_file"](#secret_file), metadata key/value pairs in the loaded file will override
key/value pairs that were previously set in a passed `metadata` hash.

### zmq\_soname

The `libzmq` dynamic library name; by default, the newest available library
is chosen.

## METHODS

### commit

Write ["public\_file"](#public_file) and ["secret\_file"](#secret_file) to disk.

### export\_zcert

Generate and return the current ZCert; the certificate is represented as a
struct-like object with two accessors, **public** and **secret**, containing
ZPL-encoded ASCII text:

    my $certdata = $zcert->export_zcert;
    my $public_zpl = $certdata->public;
    my $secret_zpl = $certdata->secret;

### generate\_keypair

Generate and return a new key pair via [zmq\_curve\_keypair(3)](http://man.he.net/man3/zmq_curve_keypair); if called as
an instance method, the current ZCert object remains unchanged.

The returned key pair is a struct-like object with two accessors, **public**
and **secret**:

    my $keypair = $zcert->generate_keypair;
    my $pub_z85 = $keypair->public;
    my $sec_z85 = $keypair->secret;

Can be called as either a class or instance method.

# SEE ALSO

[Text::ZPL](https://metacpan.org/pod/Text::ZPL)

[Convert::Z85](https://metacpan.org/pod/Convert::Z85)

[POEx::ZMQ](https://metacpan.org/pod/POEx::ZMQ)

[ZMQ::FFI](https://metacpan.org/pod/ZMQ::FFI)

# AUTHOR

Jon Portnoy <avenj@cobaltirc.org>