chiark / gitweb /
rsa1: Provide rsa1_loadpriv function
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 6 Oct 2019 21:56:08 +0000 (22:56 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 Feb 2020 21:56:49 +0000 (21:56 +0000)
We use the rsapriv_load_ctx infrastructure to provide a key loading
function suiting the scheme loadpriv interface.

I chose to use fmemopen because it is convenient.  We have an
autoconf-based portability fixup for eg BSDs (i.e., an implementation
in terms of funopen).

This is going to go in the schemes table.  It is not hooked in yet, so
won't be called.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
rsa.c
secnet.h

diff --git a/rsa.c b/rsa.c
index d5d80ff6664dbcb0e0a1d0a07960c67fb3bcbf92..28f9d865b2db2048b5f64c21683c0845f7f87cc1 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -337,6 +337,9 @@ struct rsapriv_load_ctx {
        struct {
            struct cloc loc;
        } apply;
+       struct {
+           struct log_if *log;
+       } tryload;
     } u;
 };
 
@@ -618,6 +621,59 @@ error_out:
     goto out;
 }
 
+FORMAT(printf,4,0)
+static void verror_tryload(struct rsapriv_load_ctx *l,
+                          FILE *maybe_f, bool_t unsup,
+                          const char *message, va_list args)
+{
+    int class=unsup ? M_DEBUG : M_ERR;
+    slilog_part(l->u.tryload.log,class,"rsa1priv load: ");
+    vslilog(l->u.tryload.log,class,message,args);
+}
+
+static bool_t postreadcheck_tryload(struct rsapriv_load_ctx *l, FILE *f)
+{
+    assert(!ferror(f));
+    if (feof(f)) { load_error(l,0,0,"eof mid-integer"); return False; }
+    return True;
+}
+
+bool_t rsa1_loadpriv(const struct sigscheme_info *algo,
+                    struct buffer_if *privkeydata,
+                    struct sigprivkey_if **sigpriv_r,
+                    struct log_if *log)
+{
+    FILE *f=0;
+    struct rsapriv *st=0;
+
+    f=fmemopen(privkeydata->start,privkeydata->size,"r");
+    if (!f) {
+       slilog(log,M_ERR,"failed to fmemopen private key file\n");
+       goto error_out;
+    }
+
+    struct cloc loc;
+    loc.file="dynamically loaded";
+    loc.line=0;
+
+    struct rsapriv_load_ctx l[1];
+    l->verror=verror_tryload;
+    l->postreadcheck=postreadcheck_tryload;
+    l->u.tryload.log=log;
+
+    st=rsa_loadpriv_core(l,f,loc,True);
+    if (!st) goto error_out;
+    goto out;
+
+ error_out:
+    if (st) { free(st); st=0; }
+ out:
+    if (f) fclose(f);
+    if (!st) return False;
+    *sigpriv_r=&st->ops;
+    return True;
+}
+
 static void verror_cfgfatal(struct rsapriv_load_ctx *l,
                            FILE *maybe_f, bool_t unsup,
                            const char *message, va_list args)
index 0d5b8396d9abf95e63c6a8f56c6d12b5c88ae3b8..1a26e7495c74cdc392ea91c0cf3519e69445a521 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -433,6 +433,8 @@ extern const struct sigscheme_info sigschemes[]; /* sentinel has name==0 */
 
 const struct sigscheme_info *sigscheme_lookup(const char *name);
 
+extern sigscheme_loadpriv rsa1_loadpriv;
+
 /***** END of signature schemes *****/
 
 /***** CLOSURE TYPES and interface definitions *****/