[rt-commit] r140 - in /redwax-tool/trunk: ChangeLog redwax-tool.c redwax-tool.h redwax_openssl.c

rt-commit at redwax.eu rt-commit at redwax.eu
Mon Jan 2 12:19:01 CET 2023


Author: minfrin at redwax.eu
Date: Mon Jan  2 12:18:58 2023
New Revision: 140

Log:
Add --ssh-public-out to output public keys in one line
SSH format as per RFC4253 section 6.6.

Modified:
    redwax-tool/trunk/ChangeLog
    redwax-tool/trunk/redwax-tool.c
    redwax-tool/trunk/redwax-tool.h
    redwax-tool/trunk/redwax_openssl.c

Modified: redwax-tool/trunk/ChangeLog
==============================================================================
--- redwax-tool/trunk/ChangeLog	(original)
+++ redwax-tool/trunk/ChangeLog	Mon Jan  2 12:18:58 2023
@@ -1,5 +1,9 @@
 
 Changes with v0.9.2
+
+ *) Add --ssh-public-out to output public keys in one line
+    SSH format as per RFC4253 section 6.6. [Graham
+    Leggett]
 
  *) Set metadata format default to yaml, as yaml is way
     friendlier to humans than json or xml. [Graham Leggett]

Modified: redwax-tool/trunk/redwax-tool.c
==============================================================================
--- redwax-tool/trunk/redwax-tool.c	(original)
+++ redwax-tool/trunk/redwax-tool.c	Mon Jan  2 12:18:58 2023
@@ -73,6 +73,7 @@
         APR_HOOK_LINK(complete_pkcs11_module_out);
         APR_HOOK_LINK(process_pkcs11_module_out);
         APR_HOOK_LINK(process_metadata_out);
+        APR_HOOK_LINK(process_ssh_public_out);
         APR_HOOK_LINK(complete_format_out);
         APR_HOOK_LINK(process_jwks_out);
         APR_HOOK_LINK(set_format_out);
@@ -126,6 +127,8 @@
         (redwax_tool_t * r, const char *mod, redwax_token_quoted_e quoted), (r, mod, quoted), DECLINED);
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_metadata_out,
         (redwax_tool_t * r, const char *arg), (r, arg), DECLINED);
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_ssh_public_out,
+        (redwax_tool_t * r, const char *arg, const char *secret), (r, arg, secret), DECLINED);
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, set_format_out,
         (redwax_tool_t * r, const char *arg), (r, arg), DECLINED);
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, complete_format_out,
@@ -290,10 +293,10 @@
     { "user-out", REDWAX_TOOL_USER_OUT, 1, "  --user-out=user\t\tUse the privileges of this user when writing\n\t\t\t\tcertificates and keys." },
     { "group-in", REDWAX_TOOL_GROUP_IN, 1, "  --group-in=group\t\tUse the privileges of this group when reading\n\t\t\t\tcertificates and keys. If you have set a user\n\t\t\t\tbefore setting a group, you may no longer have\n\t\t\t\tpermission to set the group. It is recommended\n\t\t\t\tthat if user and group are set, the group is set\n\t\t\t\tfirst." },
     { "group-out", REDWAX_TOOL_GROUP_OUT, 1, "  --group-out=group\t\tUse the privileges of this group when writing\n\t\t\t\tcertificates and keys. If you have set a user\n\t\t\t\tbefore setting a group, you may no longer have\n\t\t\t\tpermission to set the group. It is recommended\n\t\t\t\tthat if user and group are set, the group is set\n\t\t\t\tfirst." },
+    { "ssh-public-out", REDWAX_TOOL_SSH_PUBLIC_OUT, 1, "  --ssh-public-out=file\t\tWrite an SSH public key to the given file." },
 #if 0
     { "jwks-out", REDWAX_TOOL_JWKS_OUT, 1, "  --jwks-out=file\t\tWrite keys to the given file as an RFC7517 JSON\n\t\t\t\tWeb Key Set." },
     { "ssh-private-out", REDWAX_TOOL_SSH_PRIVATE_OUT, 1, "  --ssh-private-out=file\t\tWrite an SSH private key to the given file." },
-    { "ssh-public-out", REDWAX_TOOL_SSH_PUBLIC_OUT, 1, "  --ssh-public-out=file\t\tWrite an SSH public key to the given file." },
     { "smimea-out", REDWAX_TOOL_SMIMEA_OUT, 1, "  --smimea-out=file\t\tWrite an SMIMEA DNS record to the given file." },
     { "sshfp-out", REDWAX_TOOL_SSHFP_OUT, 1, "  --sshfp-out=file\t\tWrite an SSHFP DNS record to the given file." },
     { "tlsa-out", REDWAX_TOOL_TLSA_OUT, 1, "  --tlsa-out=file\t\tWrite a TLSA DNS record to the given file." },
@@ -2562,6 +2565,10 @@
             redwax_metadata_out(r, optarg);
             break;
         }
+        case REDWAX_TOOL_SSH_PUBLIC_OUT: {
+            redwax_file_out(r, optarg, &rt_run_process_ssh_public_out);
+            break;
+        }
         case REDWAX_TOOL_FORMAT_OUT: {
             redwax_format_out(r, optarg);
             break;

Modified: redwax-tool/trunk/redwax-tool.h
==============================================================================
--- redwax-tool/trunk/redwax-tool.h	(original)
+++ redwax-tool/trunk/redwax-tool.h	Mon Jan  2 12:18:58 2023
@@ -529,6 +529,14 @@
         (redwax_tool_t *r, const char *arg));
 
 /**
+ * Hook to write SSH public keys.
+ *
+ * @param r The redwax-tool context.
+ */
+APR_DECLARE_EXTERNAL_HOOK(rt, REDWAX, apr_status_t, process_ssh_public_out,
+        (redwax_tool_t *r, const char *arg, const char *secret));
+
+/**
  * Hook to complete the metadata format.
  *
  * @param r The redwax-tool context.

Modified: redwax-tool/trunk/redwax_openssl.c
==============================================================================
--- redwax-tool/trunk/redwax_openssl.c	(original)
+++ redwax-tool/trunk/redwax_openssl.c	Mon Jan  2 12:18:58 2023
@@ -2997,6 +2997,109 @@
     return APR_SUCCESS;
 }
 
+static void redwax_openssl_ssh_bignum(BIO *bio,
+		unsigned char *buf, apr_size_t len)
+{
+	apr_size_t padded_len = len;
+	unsigned char c;
+
+	if (buf[0] & 0x80) {
+		padded_len++;
+	}
+
+	c = padded_len >> 24;
+	BIO_write(bio, &c, 1);
+	c = padded_len >> 16;
+	BIO_write(bio, &c, 1);
+	c = padded_len >> 8;
+	BIO_write(bio, &c, 1);
+	c = padded_len;
+	BIO_write(bio, &c, 1);
+
+	if (buf[0] & 0x80) {
+		c = 0;
+		BIO_write(bio, &c, 1);
+	}
+
+	BIO_write(bio, buf, len);
+}
+
+static apr_status_t redwax_openssl_process_ssh_public_out(redwax_tool_t *r,
+        const char *file, const char *secret)
+{
+    BIO *bio;
+    int i;
+
+    if (!strcmp(file, "-")) {
+        if ((bio = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL) {
+            redwax_openssl_print_errors(r);
+            return APR_ENOMEM;
+        }
+    }
+    else if ((bio = BIO_new(BIO_s_file())) == NULL) {
+        redwax_openssl_print_errors(r);
+        return APR_ENOMEM;
+    }
+    else if (BIO_write_filename(bio, (char *)file) <= 0) {
+        redwax_openssl_print_errors(r);
+        BIO_free(bio);
+        return APR_ENOENT;
+    }
+
+    apr_pool_cleanup_register(r->pool, bio, cleanup_bio,
+            apr_pool_cleanup_null);
+
+    if (r->key_out) {
+        for (i = 0; i < r->keys_out->nelts; i++)
+        {
+            BIO *b64;
+
+            const redwax_key_t *key = &APR_ARRAY_IDX(r->keys_out, i, const redwax_key_t);
+
+            switch (key->common.type) {
+            case REDWAX_KEY_RSA: {
+
+            	static unsigned char sshHeader[11] = { 0x00, 0x00, 0x00, 0x07, 's', 's', 'h', '-', 'r', 's', 'a'};
+
+            	if (!key->rsa) {
+                    redwax_print_error(r, "ssh-public-out: no rsa components, skipping\n");
+                    break;
+                }
+
+            	b64 = BIO_new(BIO_f_base64());
+            	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+            	BIO_printf(bio, "ssh-rsa ");
+            	bio = BIO_push(b64, bio);
+
+            	BIO_write(bio, sshHeader, sizeof(sshHeader));
+
+            	redwax_openssl_ssh_bignum(bio, key->rsa->public_exponent, key->rsa->public_exponent_len);
+            	redwax_openssl_ssh_bignum(bio, key->rsa->modulus, key->rsa->modulus_len);
+
+            	BIO_flush(bio);
+            	bio = BIO_pop(b64);
+            	BIO_printf(bio, " %s\n", "label");
+            	BIO_flush(bio);
+            	BIO_free(b64);
+
+                redwax_print_error(r, "ssh-public-out: private key\n");
+
+            	break;
+            }
+            default: {
+
+                redwax_print_error(r, "ssh-public-out: unsupported key, skipping\n");
+
+            	break;
+            }
+            }
+
+        }
+    }
+
+    return APR_SUCCESS;
+}
+
 apr_status_t redwax_openssl_writev(void *ctx, const struct iovec *vec,
                 apr_size_t nvec)
 {
@@ -5181,6 +5284,7 @@
     rt_hook_process_der_out(redwax_openssl_process_der_out, NULL, NULL, APR_HOOK_MIDDLE);
     rt_hook_process_pem_out(redwax_openssl_process_pem_out, NULL, NULL, APR_HOOK_MIDDLE);
     rt_hook_process_pkcs12_out(redwax_openssl_process_pkcs12_out, NULL, NULL, APR_HOOK_MIDDLE);
+    rt_hook_process_ssh_public_out(redwax_openssl_process_ssh_public_out, NULL, NULL, APR_HOOK_MIDDLE);
     rt_hook_process_metadata_out(redwax_openssl_process_metadata_out, NULL, NULL, APR_HOOK_MIDDLE);
     rt_hook_complete_format_out(redwax_openssl_complete_format_out, NULL, NULL, APR_HOOK_MIDDLE);
     rt_hook_set_format_out(redwax_openssl_set_format_out, NULL, NULL, APR_HOOK_MIDDLE);



More information about the rt-commit mailing list