zarmour(3)
Class for armoured text encoding and decoding
Description
ZARMOUR
NAME
zarmour - Class for armoured text encoding and decoding
SYNOPSIS
// This is a
stable class, and may not change except for emergencies. It
// is provided in stable builds.
#define ZARMOUR_MODE_BASE64_STD 0 // Standard base 64
#define ZARMOUR_MODE_BASE64_URL 1 // URL and filename
friendly base 64
#define ZARMOUR_MODE_BASE32_STD 2 // Standard base 32
#define ZARMOUR_MODE_BASE32_HEX 3 // Extended hex base 32
#define ZARMOUR_MODE_BASE16 4 // Standard base 16
#define ZARMOUR_MODE_Z85 5 // Z85 from ZeroMQ RFC 32
// Create a new
zarmour
CZMQ_EXPORT zarmour_t *
zarmour_new (void);
// Destroy the
zarmour
CZMQ_EXPORT void
zarmour_destroy (zarmour_t **self_p);
// Encode a
stream of bytes into an armoured string. Returns the
armoured
// string, or NULL if there was insufficient memory
available to allocate
// a new string.
// Caller owns return value and must destroy it when done.
CZMQ_EXPORT char *
zarmour_encode (zarmour_t *self, const byte *data, size_t
size);
// Decode an
armoured string into a chunk. The decoded output is
// null-terminated, so it may be treated as a string, if
that's what
// it was prior to encoding.
// Caller owns return value and must destroy it when done.
CZMQ_EXPORT zchunk_t *
zarmour_decode (zarmour_t *self, const char *data);
// Get the mode
property.
CZMQ_EXPORT int
zarmour_mode (zarmour_t *self);
// Get printable
string for mode.
CZMQ_EXPORT const char *
zarmour_mode_str (zarmour_t *self);
// Set the mode
property.
CZMQ_EXPORT void
zarmour_set_mode (zarmour_t *self, int mode);
// Return true
if padding is turned on.
CZMQ_EXPORT bool
zarmour_pad (zarmour_t *self);
// Turn padding
on or off. Default is on.
CZMQ_EXPORT void
zarmour_set_pad (zarmour_t *self, bool pad);
// Get the
padding character.
CZMQ_EXPORT char
zarmour_pad_char (zarmour_t *self);
// Set the
padding character.
CZMQ_EXPORT void
zarmour_set_pad_char (zarmour_t *self, char pad_char);
// Return if
splitting output into lines is turned on. Default is off.
CZMQ_EXPORT bool
zarmour_line_breaks (zarmour_t *self);
// Turn
splitting output into lines on or off.
CZMQ_EXPORT void
zarmour_set_line_breaks (zarmour_t *self, bool
line_breaks);
// Get the line
length used for splitting lines.
CZMQ_EXPORT size_t
zarmour_line_length (zarmour_t *self);
// Set the line
length used for splitting lines.
CZMQ_EXPORT void
zarmour_set_line_length (zarmour_t *self, size_t
line_length);
// Print
properties of object
CZMQ_EXPORT void
zarmour_print (zarmour_t *self);
// Self test of
this class.
CZMQ_EXPORT void
zarmour_test (bool verbose);
Please add '@interface' section in './../src/zarmour.c'.
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);
int
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);
zchunk_t
*chunk = zarmour_decode (self,
"4E6F87E2FB6EB22A1EF5E257B75D79124949565F0B8B36A878A4F03111C96E0B");
assert (chunk);
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 *) zchunk_data (chunk),
"ph+{E}!&X?9}!I]W{sm(nL8@&3Yu{wC+<*-5Y[[#",
verbose);
zchunk_destroy (&chunk);
#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 index;
for (index = 0; index < 256; index++)
test_data [index] = index;
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);
#if
defined (__WINDOWS__)
zsys_shutdown();
#endif
AUTHORS
The czmq manual was written by the authors in the AUTHORS file.
RESOURCES
Main web site:
Report bugs to the email <zeromq-dev@lists.zeromq.org [1] >
COPYRIGHT
Copyright (c) the Contributors as noted in the AUTHORS file. This file is part of CZMQ, the high-level C binding for 0MQ: 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/. LICENSE included with the czmq distribution.
NOTES
|
1. |
zeromq-dev@lists.zeromq.org |
mailto:zeromq-dev@lists.zeromq.org