Module Name: src
Committed By: agc
Date: Mon Sep 6 18:16:52 UTC 2010
Added Files:
src/crypto/external/bsd/netpgp/dist/src/pgp2ssh: b64.c b64.h main.c
pgp2ssh.1
Log Message:
Add pgp2ssh, a utility to retrieve PGP keys via HKP, and to store the keys
in ssh format. In combination with hkpd (using ssh key files), this utility
can be used to distribute ssh pubkey files to remote computers using the
HKP protocol.
To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.c \
src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.h \
src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/main.c \
src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/pgp2ssh.1
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Added files:
Index: src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.c
diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.c:1.1
--- /dev/null Mon Sep 6 18:16:52 2010
+++ src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.c Mon Sep 6 18:16:52 2010
@@ -0,0 +1,339 @@
+/*********************************************************************\
+
+MODULE NAME: b64.c
+
+AUTHOR: Bob Trower 08/04/01
+
+PROJECT: Crypt Data Packaging
+
+COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001
+
+NOTE: This source code may be used as you wish, subject to
+ the MIT license. See the LICENCE section below.
+
+DESCRIPTION:
+ This little utility implements the Base64
+ Content-Transfer-Encoding standard described in
+ RFC1113 (http://www.faqs.org/rfcs/rfc1113.html).
+
+ This is the coding scheme used by MIME to allow
+ binary data to be transferred by SMTP mail.
+
+ Groups of 3 bytes from a binary stream are coded as
+ groups of 4 bytes in a text stream.
+
+ The input stream is 'padded' with zeros to create
+ an input that is an even multiple of 3.
+
+ A special character ('=') is used to denote padding so
+ that the stream can be decoded back to its exact size.
+
+ Encoded output is formatted in lines which should
+ be a maximum of 72 characters to conform to the
+ specification. This program defaults to 72 characters,
+ but will allow more or less through the use of a
+ switch. The program enforces a minimum line size
+ of 4 characters.
+
+ Example encoding:
+
+ The stream 'ABCD' is 32 bits long. It is mapped as
+ follows:
+
+ ABCD
+
+ A (65) B (66) C (67) D (68) (None) (None)
+ 01000001 01000010 01000011 01000100
+
+ 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=)
+ 010000 010100 001001 000011 010001 000000 000000 000000
+
+
+ QUJDRA==
+
+ Decoding is the process in reverse. A 'decode' lookup
+ table has been created to avoid string scans.
+
+DESIGN GOALS: Specifically:
+ Code is a stand-alone utility to perform base64
+ encoding/decoding. It should be genuinely useful
+ when the need arises and it meets a need that is
+ likely to occur for some users.
+ Code acts as sample code to show the author's
+ design and coding style.
+
+ Generally:
+ This program is designed to survive:
+ Everything you need is in a single source file.
+ It compiles cleanly using a vanilla ANSI C compiler.
+ It does its job correctly with a minimum of fuss.
+ The code is not overly clever, not overly simplistic
+ and not overly verbose.
+ Access is 'cut and paste' from a web page.
+ Terms of use are reasonable.
+
+VALIDATION: Non-trivial code is never without errors. This
+ file likely has some problems, since it has only
+ been tested by the author. It is expected with most
+ source code that there is a period of 'burn-in' when
+ problems are identified and corrected. That being
+ said, it is possible to have 'reasonably correct'
+ code by following a regime of unit test that covers
+ the most likely cases and regression testing prior
+ to release. This has been done with this code and
+ it has a good probability of performing as expected.
+
+ Unit Test Cases:
+
+ case 0:empty file:
+ CASE0.DAT -> ->
+ (Zero length target file created
+ on both encode and decode.)
+
+ case 1:One input character:
+ CASE1.DAT A -> QQ== -> A
+
+ case 2:Two input characters:
+ CASE2.DAT AB -> QUJD -> AB
+
+ case 3:Three input characters:
+ CASE3.DAT ABC -> QUJD -> ABC
+
+ case 4:Four input characters:
+ case4.dat ABCD -> QUJDRA== -> ABCD
+
+ case 5:All chars from 0 to ff, linesize set to 50:
+
+ AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj
+ JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH
+ SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr
+ bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P
+ kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz
+ tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX
+ 2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7
+ /P3+/w==
+
+ case 6:Mime Block from e-mail:
+ (Data same as test case 5)
+
+ case 7: Large files:
+ Tested 28 MB file in/out.
+
+ case 8: Random Binary Integrity:
+ This binary program (b64.exe) was encoded to base64,
+ back to binary and then executed.
+
+ case 9 Stress:
+ All files in a working directory encoded/decoded
+ and compared with file comparison utility to
+ ensure that multiple runs do not cause problems
+ such as exhausting file handles, tmp storage, etc.
+
+ -------------
+
+ Syntax, operation and failure:
+ All options/switches tested. Performs as
+ expected.
+
+ case 10:
+ No Args -- Shows Usage Screen
+ Return Code 1 (Invalid Syntax)
+ case 11:
+ One Arg (invalid) -- Shows Usage Screen
+ Return Code 1 (Invalid Syntax)
+ case 12:
+ One Arg Help (-?) -- Shows detailed Usage Screen.
+ Return Code 0 (Success -- help request is valid).
+ case 13:
+ One Arg Help (-h) -- Shows detailed Usage Screen.
+ Return Code 0 (Success -- help request is valid).
+ case 14:
+ One Arg (valid) -- Uses stdin/stdout (filter)
+ Return Code 0 (Sucess)
+ case 15:
+ Two Args (invalid file) -- shows system error.
+ Return Code 2 (File Error)
+ case 16:
+ Encode non-existent file -- shows system error.
+ Return Code 2 (File Error)
+ case 17:
+ Out of disk space -- shows system error.
+ Return Code 3 (File I/O Error)
+
+ -------------
+
+ Compile/Regression test:
+ gcc compiled binary under Cygwin
+ Microsoft Visual Studio under Windows 2000
+ Microsoft Version 6.0 C under Windows 2000
+
+DEPENDENCIES: None
+
+LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated
+ documentation files (the "Software"), to deal in the
+ Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall
+ be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+VERSION HISTORY:
+ Bob Trower 08/04/01 -- Create Version 0.00.00B
+
+\******************************************************************* */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "b64.h"
+
+/*
+** Translation Table as described in RFC1113
+*/
+static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*
+** Translation Table to decode (created by author)
+*/
+static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?...@abcdefghijklmnopqrstuvw$$$$$$xyz[\\]^_`abcdefghijklmnopq";
+
+/*
+** encodeblock
+**
+** encode 3 8-bit binary bytes as 4 '6-bit' characters
+*/
+static void
+encodeblock(uint8_t *wordin, uint8_t *wordout, int wordlen)
+{
+ wordout[0] = cb64[(unsigned)wordin[0] >> 2];
+ wordout[1] = cb64[((unsigned)(wordin[0] & 0x03) << 4) | ((unsigned)(wordin[1] & 0xf0) >> 4)];
+ wordout[2] = (uint8_t)(wordlen > 1) ?
+ cb64[((unsigned)(wordin[1] & 0x0f) << 2) | ((unsigned)(wordin[2] & 0xc0) >> 6)] : '=';
+ wordout[3] = (uint8_t)(wordlen > 2) ? cb64[wordin[2] & 0x3f] : '=';
+}
+
+/*
+** encode
+**
+** base64 encode a stream adding padding and line breaks as per spec.
+*/
+int
+b64encode(const char *in, const size_t insize, void *vp, size_t outsize, int linesize)
+{
+ const char *inp;
+ unsigned i;
+ uint8_t wordout[4];
+ uint8_t wordin[3];
+ char *out = vp;
+ char *outp;
+ int blocksout;
+ int wordlen;
+
+ for (blocksout = 0, inp = in, outp = out; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize;) {
+ for (wordlen = 0, i = 0; i < sizeof(wordin); i++) {
+ wordin[i] = (uint8_t) *inp++;
+ if ((size_t)(inp - in) <= insize) {
+ wordlen++;
+ } else {
+ wordin[i] = 0x0;
+ }
+ }
+ if (wordlen > 0) {
+ encodeblock(wordin, wordout, wordlen);
+ for (i = 0; i < sizeof(wordout) ; i++) {
+ *outp++ = wordout[i];
+ }
+ blocksout++;
+ }
+ if (blocksout >= (int)(linesize / sizeof(wordout)) ||
+ (size_t)(inp - in) >= insize) {
+ if (blocksout) {
+ *outp++ = '\r';
+ *outp++ = '\n';
+ }
+ blocksout = 0;
+ }
+ }
+ return (int)(outp - out);
+}
+
+/*
+** decodeblock
+**
+** decode 4 '6-bit' characters into 3 8-bit binary bytes
+*/
+static void
+decodeblock(uint8_t wordin[4], uint8_t wordout[3])
+{
+ wordout[0] = (uint8_t) ((unsigned)wordin[0] << 2 | (unsigned)wordin[1] >> 4);
+ wordout[1] = (uint8_t) ((unsigned)wordin[1] << 4 | (unsigned)wordin[2] >> 2);
+ wordout[2] = (uint8_t) (((wordin[2] << 6) & 0xc0) | wordin[3]);
+}
+
+/*
+** decode
+**
+** decode a base64 encoded stream discarding padding, line breaks and noise
+*/
+int
+b64decode(const char *in, const size_t insize, void *vp, size_t outsize)
+{
+ const char *inp;
+ uint8_t wordout[3];
+ uint8_t wordin[4];
+ uint8_t v;
+ char *out = vp;
+ char *outp;
+ int wordlen;
+ int i;
+
+ for (inp = in, outp = out ; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize ; ) {
+ for (wordlen = 0, i = 0 ; i < 4 && (size_t)(inp - in) < insize ; i++) {
+ /* get a single character */
+ for (v = 0; (size_t)(inp - in) < insize && v == 0 ; ) {
+ if (*inp == '\r' && *(inp + 1) == '\n') {
+ inp += 2;
+ } else {
+ v = (uint8_t) *inp++;
+ v = (uint8_t) ((v < 43 || v > 122) ? 0 : cd64[v - 43]);
+ if (v) {
+ v = (uint8_t) ((v == '$') ? 0 : v - 61);
+ }
+ }
+ }
+ /* perhaps 0 pad */
+ if ((size_t)(inp - in) < insize) {
+ wordlen += 1;
+ if (v) {
+ wordin[i] = (uint8_t) (v - 1);
+ }
+ } else {
+ wordin[i] = 0x0;
+ }
+ }
+ if (wordlen > 0) {
+ decodeblock(wordin, wordout);
+ for (i = 0; i < wordlen - 1 ; i++) {
+ *outp++ = wordout[i];
+ }
+ }
+ }
+ return (int)(outp - out);
+}
Index: src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.h
diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.h:1.1
--- /dev/null Mon Sep 6 18:16:52 2010
+++ src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/b64.h Mon Sep 6 18:16:52 2010
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Alistair Crooks ([email protected])
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef B64_H_
+#define B64_H_ 20091223
+
+int b64encode(const char *in, const size_t insize, void *vp, size_t outsize, int linesize);
+int b64decode(const char *in, const size_t insize, void *vp, size_t outsize);
+
+#endif
Index: src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/main.c
diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/main.c:1.1
--- /dev/null Mon Sep 6 18:16:52 2010
+++ src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/main.c Mon Sep 6 18:16:52 2010
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 2010 Alistair Crooks <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <inttypes.h>
+#include <netpgp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "b64.h"
+#include "hkpc.h"
+
+#define DEFAULT_NUMBITS 2048
+
+#define DEFAULT_HASH_ALG "SHA256"
+
+int
+main(int argc, char **argv)
+{
+ netpgp_t netpgp;
+ char *res;
+ char key[8192];
+ char asc[8192];
+ char server[BUFSIZ];
+ char *cp;
+ int family;
+ int port;
+ int keyc;
+ int ascc;
+ int ok;
+ int i;
+
+ (void) memset(&netpgp, 0x0, sizeof(netpgp));
+ port = 11371;
+ family = 4;
+ (void) snprintf(server, sizeof(server), "localhost");
+ while ((i = getopt(argc, argv, "f:h:p:")) != -1) {
+ switch(i) {
+ case 'f':
+ family = atoi(optarg);
+ break;
+ case 'h':
+ (void) snprintf(server, sizeof(server), optarg);
+ break;
+ case 'p':
+ port = atoi(optarg);
+ break;
+ default:
+ break;
+ }
+ }
+ netpgp_setvar(&netpgp, "ssh keys", "1");
+ netpgp_setvar(&netpgp, "hash", DEFAULT_HASH_ALG);
+ netpgp_set_homedir(&netpgp, getenv("HOME"), "/.ssh", 1);
+ for (ok = 1, i = optind ; i < argc ; i++) {
+ if (!hkpc_get(&res, server, port, family, "get", argv[i])) {
+ (void) fprintf(stderr, "No such key '%s'\n", argv[i]);
+ ok = 0;
+ }
+ if ((keyc = netpgp_write_sshkey(&netpgp, res, argv[i], key, sizeof(key))) <= 0) {
+ (void) fprintf(stderr, "can't netpgp_write_sshkey '%s'\n", argv[i]);
+ ok = 0;
+ }
+ for (cp = &key[keyc - 1] ; cp > key && *cp != ' ' ; --cp) {
+ }
+ if (cp == key) {
+ cp = argv[i];
+ } else {
+ cp += 1;
+ }
+ /* btoa */
+ ascc = b64encode(key, keyc, asc, sizeof(asc), 0xffffffff);
+ /* write to .ssh/id_c0596823.pub */
+ printf("ssh-rsa %.*s %s\n", ascc - 2, asc, cp);
+ }
+ exit((ok) ? EXIT_SUCCESS : EXIT_FAILURE);
+}
Index: src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/pgp2ssh.1
diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/pgp2ssh.1:1.1
--- /dev/null Mon Sep 6 18:16:52 2010
+++ src/crypto/external/bsd/netpgp/dist/src/pgp2ssh/pgp2ssh.1 Mon Sep 6 18:16:52 2010
@@ -0,0 +1,100 @@
+.\" $NetBSD: pgp2ssh.1,v 1.1 2010/09/06 18:16:52 agc Exp $
+.\"
+.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This manual page is derived from software contributed to
+.\" The NetBSD Foundation by Alistair Crooks ([email protected]).
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd September 6, 2010
+.Dt PGP2SSH 1
+.Os
+.Sh NAME
+.Nm pgp2ssh
+.Nd convert a PGP public key to an SSHv2 key
+.Sh SYNOPSIS
+.Nm
+.Op Fl f address-family
+.Op Fl h hostname
+.Op Fl p port
+userid...
+.Sh DESCRIPTION
+The
+.Nm
+command retrieves PGP public key information from the key server daemon
+using the HKP protocol, and converts the PGP public
+key to a format suitable for use by
+.Xr ssh 1
+The
+.Xr hkpd 1
+is normally used to serve public key information.
+The
+.Nm
+utility is similar to the
+.Xr hkpc 1
+utility in that it retrieves keys in the same way.
+In addition,
+.Nm
+will convert the format of the key.
+.Pp
+At the present time, only RSA keys are supported.
+There is no intention, at the time of writing, to
+support DSA keys, due to their limitations.
+.Pp
+It is quite possible to serve ssh public keys
+across a network using
+.Xr hkpd 1
+to
+serve the key, and
+.Nm
+to retrieve the key using the HKP protocol,
+and to save the key in ssh format on the remote computer,
+allowing users to login to the remote computer using
+.Xr ssh 1 .
+.Sh EXIT STATUS
+The
+.Nm
+utility will return 0 for success,
+or 1 for failure.
+Output will be printed on stdout.
+It can be redirected to a file for use by
+.Xr ssh 1 .
+.Sh SEE ALSO
+.Xr hkpc 1 ,
+.Xr hkpd 1 ,
+.Xr netpgpkeys 1 ,
+.Xr ssh 1 ,
+.\" .Xr libbz2 3 ,
+.Xr libnetpgp 3
+.Sh STANDARDS
+The
+.Nm
+utility is designed to conform to IETF RFC 4880.
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Nx 6.0 .
+.Sh AUTHORS
+.An Alistair Crooks Aq [email protected] .