zarmour(3)

zarmour(3)

CZMQ Manual - CZMQ/3.0.1

Name

zarmour - armoured text encoding and decoding

Synopsis

//  Enumeration defining different encoding modes
typedef enum {
      ZARMOUR_MODE_BASE64_STD   //  Standard base 64
    , ZARMOUR_MODE_BASE64_URL   //  URL and filename friendly base 64
    , ZARMOUR_MODE_BASE32_STD   //  Standard base 32
    , ZARMOUR_MODE_BASE32_HEX   //  Extended hex base 32
    , ZARMOUR_MODE_BASE16       //  Standard base 16
#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (3, 3, 0))
    , ZARMOUR_MODE_Z85          //  Z85 from ZeroMQ RFC 32
#endif
} zarmour_mode_t;

//  Create a new zarmour
CZMQ_EXPORT zarmour_t *
    zarmour_new ();

//  Destroy the zarmour
CZMQ_EXPORT void
    zarmour_destroy (zarmour_t **self_p);

//  Print properties of object
CZMQ_EXPORT void
    zarmour_print (zarmour_t *self);

//  Get printable string for mode
CZMQ_EXPORT const char *
    zarmour_mode_str (zarmour_t *self);

//  Encode a stream of bytes into an armoured string.
CZMQ_EXPORT char *
    zarmour_encode (zarmour_t *self, const byte *data, size_t data_size);

//  Decode an armoured string into a string of bytes.
//  The decoded output is null-terminated, so it may be treated
//  as a string, if that's what it was prior to encoding.
CZMQ_EXPORT byte *
    zarmour_decode (zarmour_t *self, const char *data, size_t *decode_size);

//  Get/set the mode property
CZMQ_EXPORT zarmour_mode_t
    zarmour_mode (zarmour_t *self);
CZMQ_EXPORT void
    zarmour_set_mode (zarmour_t *self, zarmour_mode_t mode);

//  Get/set the pad property
CZMQ_EXPORT bool
    zarmour_pad (zarmour_t *self);
CZMQ_EXPORT void
    zarmour_set_pad (zarmour_t *self, bool pad);

//  Get/set the pad_char property
CZMQ_EXPORT char
    zarmour_pad_char (zarmour_t *self);
CZMQ_EXPORT void
    zarmour_set_pad_char (zarmour_t *self, char pad_char);

//  Get/set the line_breaks property
CZMQ_EXPORT bool
    zarmour_line_breaks (zarmour_t *self);
CZMQ_EXPORT void
    zarmour_set_line_breaks (zarmour_t *self, bool line_breaks);

//  Get/set the line_length property
CZMQ_EXPORT size_t
    zarmour_line_length (zarmour_t *self);
CZMQ_EXPORT void
    zarmour_set_line_length (zarmour_t *self, size_t line_length);

//  Self test of this class
CZMQ_EXPORT int
    zarmour_test (bool verbose);

Description

zarmour - armoured text encoding and decoding

The zarmour class implements encoding and decoding of armoured text data. The following codecs are implemented: * RFC 4648 (http://www.ietf.org/rfc/rfc4648.txt) - base64 - base64url - base32 - base32hex - base16 * Z85 (http://rfc.zeromq.org/spec:32) All RFC4648 base64 and base32 variants support padding the output. The pad character is configurable. Default is padding on, with character =. Additionally, in some cases (e.g. MIME), splitting the output into lines of a specific length is required. This feature is also supported, though turned off by default. The z85 mode does neither padding nor line breaks; it is merely a wrapping of the corresponding libzmq methods. Encoding will assert if input length is not divisible by 4 and decoding will assert if input length is not divisible by 5.

Example

From zarmour_test method

zarmour_t *self = zarmour_new ();
assert (self);

zarmour_mode_t mode = zarmour_mode (self);
assert (mode == ZARMOUR_MODE_BASE64_STD);

zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL);
mode = zarmour_mode (self);
assert (mode == ZARMOUR_MODE_BASE64_URL);

assert (zarmour_pad (self));
zarmour_set_pad (self, false);
assert (!zarmour_pad (self));

assert (zarmour_pad_char (self) == '=');
zarmour_set_pad_char (self, '!');
assert (zarmour_pad_char (self) == '!');
zarmour_set_pad_char (self, '=');
assert (zarmour_pad_char (self) == '=');

assert (!zarmour_line_breaks (self));
zarmour_set_line_breaks (self, true);
assert (zarmour_line_breaks (self));

assert (zarmour_line_length (self) == 72);
zarmour_set_line_length (self, 64);
assert (zarmour_line_length (self) == 64);

// Test against test vectors from RFC4648.
zarmour_set_mode (self, ZARMOUR_MODE_BASE64_STD);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "Zg", verbose);
s_armour_test (self, "fo", "Zm8", verbose);
s_armour_test (self, "foo", "Zm9v", verbose);
s_armour_test (self, "foob", "Zm9vYg", verbose);
s_armour_test (self, "fooba", "Zm9vYmE", verbose);
s_armour_test (self, "foobar", "Zm9vYmFy", verbose);
zarmour_set_pad (self, true);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "Zg==", verbose);
s_armour_test (self, "fo", "Zm8=", verbose);
s_armour_test (self, "foo", "Zm9v", verbose);
s_armour_test (self, "foob", "Zm9vYg==", verbose);
s_armour_test (self, "fooba", "Zm9vYmE=", verbose);
s_armour_test (self, "foobar", "Zm9vYmFy", verbose);

zarmour_set_pad (self, false);
zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "Zg", verbose);
s_armour_test (self, "fo", "Zm8", verbose);
s_armour_test (self, "foo", "Zm9v", verbose);
s_armour_test (self, "foob", "Zm9vYg", verbose);
s_armour_test (self, "fooba", "Zm9vYmE", verbose);
s_armour_test (self, "foobar", "Zm9vYmFy", verbose);
zarmour_set_pad (self, true);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "Zg==", verbose);
s_armour_test (self, "fo", "Zm8=", verbose);
s_armour_test (self, "foo", "Zm9v", verbose);
s_armour_test (self, "foob", "Zm9vYg==", verbose);
s_armour_test (self, "fooba", "Zm9vYmE=", verbose);
s_armour_test (self, "foobar", "Zm9vYmFy", verbose);

zarmour_set_pad (self, false);
zarmour_set_mode (self, ZARMOUR_MODE_BASE32_STD);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "MY", verbose);
s_armour_test (self, "fo", "MZXQ", verbose);
s_armour_test (self, "foo", "MZXW6", verbose);
s_armour_test (self, "foob", "MZXW6YQ", verbose);
s_armour_test (self, "fooba", "MZXW6YTB", verbose);
s_armour_test (self, "foobar", "MZXW6YTBOI", verbose);
s_armour_decode (self, "my", "f", verbose);
s_armour_decode (self, "mzxq", "fo", verbose);
s_armour_decode (self, "mzxw6", "foo", verbose);
s_armour_decode (self, "mzxw6yq", "foob", verbose);
s_armour_decode (self, "mzxw6ytb", "fooba", verbose);
s_armour_decode (self, "mzxw6ytboi", "foobar", verbose);
zarmour_set_pad (self, true);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "MY======", verbose);
s_armour_test (self, "fo", "MZXQ====", verbose);
s_armour_test (self, "foo", "MZXW6===", verbose);
s_armour_test (self, "foob", "MZXW6YQ=", verbose);
s_armour_test (self, "fooba", "MZXW6YTB", verbose);
s_armour_test (self, "foobar", "MZXW6YTBOI======", verbose);
s_armour_decode (self, "my======", "f", verbose);
s_armour_decode (self, "mzxq====", "fo", verbose);
s_armour_decode (self, "mzxw6===", "foo", verbose);
s_armour_decode (self, "mzxw6yq=", "foob", verbose);
s_armour_decode (self, "mzxw6ytb", "fooba", verbose);
s_armour_decode (self, "mzxw6ytboi======", "foobar", verbose);

zarmour_set_pad (self, false);
zarmour_set_mode (self, ZARMOUR_MODE_BASE32_HEX);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "CO", verbose);
s_armour_test (self, "fo", "CPNG", verbose);
s_armour_test (self, "foo", "CPNMU", verbose);
s_armour_test (self, "foob", "CPNMUOG", verbose);
s_armour_test (self, "fooba", "CPNMUOJ1", verbose);
s_armour_test (self, "foobar", "CPNMUOJ1E8", verbose);
s_armour_decode (self, "co", "f", verbose);
s_armour_decode (self, "cpng", "fo", verbose);
s_armour_decode (self, "cpnmu", "foo", verbose);
s_armour_decode (self, "cpnmuog", "foob", verbose);
s_armour_decode (self, "cpnmuoj1", "fooba", verbose);
s_armour_decode (self, "cpnmuoj1e8", "foobar", verbose);
zarmour_set_pad (self, true);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "CO======", verbose);
s_armour_test (self, "fo", "CPNG====", verbose);
s_armour_test (self, "foo", "CPNMU===", verbose);
s_armour_test (self, "foob", "CPNMUOG=", verbose);
s_armour_test (self, "fooba", "CPNMUOJ1", verbose);
s_armour_test (self, "foobar", "CPNMUOJ1E8======", verbose);
s_armour_decode (self, "co======", "f", verbose);
s_armour_decode (self, "cpng====", "fo", verbose);
s_armour_decode (self, "cpnmu===", "foo", verbose);
s_armour_decode (self, "cpnmuog=", "foob", verbose);
s_armour_decode (self, "cpnmuoj1", "fooba", verbose);
s_armour_decode (self, "cpnmuoj1e8======", "foobar", verbose);
zarmour_set_pad (self, true);

zarmour_set_mode (self, ZARMOUR_MODE_BASE16);
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "f", "66", verbose);
s_armour_test (self, "fo", "666F", verbose);
s_armour_test (self, "foo", "666F6F", verbose);
s_armour_test (self, "foob", "666F6F62", verbose);
s_armour_test (self, "fooba", "666F6F6261", verbose);
s_armour_test (self, "foobar", "666F6F626172", verbose);
s_armour_decode (self, "666f", "fo", verbose);
s_armour_decode (self, "666f6f", "foo", verbose);
s_armour_decode (self, "666f6f62", "foob", verbose);
s_armour_decode (self, "666f6f6261", "fooba", verbose);
s_armour_decode (self, "666f6f626172", "foobar", verbose);

#ifdef _INCLUDE_Z85
// Z85 test is homemade; using 0, 4 and 8 bytes, with precalculated
// test vectors created with a libzmq test.
// ----------------------------------------------------------------

// Make a fake curve key from hex (base16) string, making sure
// there are no null bytes inside, so we can use our test utility
zarmour_set_mode (self, ZARMOUR_MODE_BASE16);
zarmour_set_line_breaks (self, false);
size_t key_len;
byte *key_data = zarmour_decode (self,
 "4E6F87E2FB6EB22A1EF5E257B75D79124949565F0B8B36A878A4F03111C96E0B",
 &key_len);

zarmour_set_mode (self, ZARMOUR_MODE_Z85); // Z85 mode does not support padding or line breaks
zarmour_set_pad (self, false); // so these two are superfluous;
zarmour_set_line_breaks (self, false); // just for consistency
if (verbose)
 zarmour_print (self);
s_armour_test (self, "", "", verbose);
s_armour_test (self, "foob", "w]zP%", verbose);
s_armour_test (self, "foobar!!", "w]zP%vr9Im", verbose);
s_armour_test (self, (char *) key_data, "ph+{E}!&X?9}!I]W{sm(nL8@&3Yu{wC+<*-5Y[[#", verbose);
free (key_data);
#endif

// Armouring longer byte array to test line breaks
zarmour_set_pad (self, true);
zarmour_set_line_breaks (self, true);
byte test_data[256];
int i;
for (i = 0; i < 256; ++i) {
 test_data[i] = i;
}
zarmour_set_mode (self, ZARMOUR_MODE_BASE64_STD);
s_armour_test_long (self, test_data, 256, verbose);
zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL);
s_armour_test_long (self, test_data, 256, verbose);
zarmour_set_mode (self, ZARMOUR_MODE_BASE32_STD);
s_armour_test_long (self, test_data, 256, verbose);
zarmour_set_mode (self, ZARMOUR_MODE_BASE32_HEX);
s_armour_test_long (self, test_data, 256, verbose);
zarmour_set_mode (self, ZARMOUR_MODE_BASE16);
s_armour_test_long (self, test_data, 256, verbose);
#ifdef _INCLUDE_Z85
zarmour_set_mode (self, ZARMOUR_MODE_Z85);
s_armour_test_long (self, test_data, 256, verbose);
#endif
 zarmour_destroy (&self);

See also

czmq(7)

Authors

The CZMQ manual was written by Pieter Hintjens<moc.xitami|hp#moc.xitami|hp>.

Resources

Main web site: http://czmq.zeromq.org/

Report bugs to the ØMQ development mailing list: <gro.qmorez.stsil|ved-qmorez#gro.qmorez.stsil|ved-qmorez>

Copyright

Copyright (c) the Contributors as noted in the AUTHORS file. This file is part of CZMQ, the high-level C binding for ØMQ: http://czmq.zeromq.org. This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.