URI: 
       tadd others - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 57fcfc2a0b8ecd266ce130dab9a29b7ceb558d64
   DIR parent ce94dbe662155bd60d6839b5e8c82ad708667bcd
  HTML Author: rsc <devnull@localhost>
       Date:   Sun, 13 Feb 2005 18:04:20 +0000
       
       add others
       
       Diffstat:
         A src/cmd/auth/asn12dsa.c             |      70 +++++++++++++++++++++++++++++++
         A src/cmd/auth/asn12rsa.c             |      71 +++++++++++++++++++++++++++++++
         A src/cmd/auth/dsa2ssh.c              |      48 +++++++++++++++++++++++++++++++
         A src/cmd/auth/dsagen.c               |      50 +++++++++++++++++++++++++++++++
         A src/cmd/auth/passwd.c               |     153 +++++++++++++++++++++++++++++++
         A src/cmd/auth/pemdecode.c            |      59 +++++++++++++++++++++++++++++++
         A src/cmd/auth/pemencode.c            |      64 +++++++++++++++++++++++++++++++
         A src/cmd/auth/respond.c              |      35 +++++++++++++++++++++++++++++++
         A src/cmd/auth/rsa2any.c              |     303 +++++++++++++++++++++++++++++++
         A src/cmd/auth/rsa2csr.c              |      43 ++++++++++++++++++++++++++++++
         A src/cmd/auth/rsa2pub.c              |      44 +++++++++++++++++++++++++++++++
         A src/cmd/auth/rsa2ssh.c              |      56 +++++++++++++++++++++++++++++++
         A src/cmd/auth/rsa2x509.c             |      50 +++++++++++++++++++++++++++++++
         A src/cmd/auth/rsafill.c              |      46 +++++++++++++++++++++++++++++++
         A src/cmd/auth/rsagen.c               |      60 +++++++++++++++++++++++++++++++
         A src/cmd/auth/userpasswd.c           |      34 +++++++++++++++++++++++++++++++
       
       16 files changed, 1186 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/src/cmd/auth/asn12dsa.c b/src/cmd/auth/asn12dsa.c
       t@@ -0,0 +1,70 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <mp.h>
       +#include <libsec.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "auth/asn12dsa [-t tag] [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char *s;
       +        uchar *buf;
       +        int fd;
       +        long n, tot;
       +        char *tag, *file;
       +        DSApriv *key;
       +
       +        fmtinstall('B', mpfmt);
       +
       +        tag = nil;
       +        ARGBEGIN{
       +        case 't':
       +                tag = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 0 && argc != 1)
       +                usage();
       +
       +        if(argc == 1)
       +                file = argv[0];
       +        else
       +                file = "/dev/stdin";
       +
       +        if((fd = open(file, OREAD)) < 0)
       +                sysfatal("open %s: %r", file);
       +        buf = nil;
       +        tot = 0;
       +        for(;;){
       +                buf = realloc(buf, tot+8192);
       +                if(buf == nil)
       +                        sysfatal("realloc: %r");
       +                if((n = read(fd, buf+tot, 8192)) < 0)
       +                        sysfatal("read: %r");
       +                if(n == 0)
       +                        break;
       +                tot += n;
       +        }
       +
       +        key = asn1toDSApriv(buf, tot);
       +        if(key == nil)
       +                sysfatal("couldn't parse asn1 key");
       +
       +        s = smprint("key proto=dsa %s%sp=%B q=%B alpha=%B key=%B !secret=%B\n",
       +                tag ? tag : "", tag ? " " : "",
       +                key->pub.p, key->pub.q, key->pub.alpha, key->pub.key,
       +                key->secret);
       +        if(s == nil)
       +                sysfatal("smprint: %r");
       +        write(1, s, strlen(s));
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/asn12rsa.c b/src/cmd/auth/asn12rsa.c
       t@@ -0,0 +1,71 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <mp.h>
       +#include <libsec.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "auth/asn12rsa [-t tag] [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char *s;
       +        uchar *buf;
       +        int fd;
       +        long n, tot;
       +        char *tag, *file;
       +        RSApriv *key;
       +
       +        fmtinstall('B', mpfmt);
       +
       +        tag = nil;
       +        ARGBEGIN{
       +        case 't':
       +                tag = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 0 && argc != 1)
       +                usage();
       +
       +        if(argc == 1)
       +                file = argv[0];
       +        else
       +                file = "/dev/stdin";
       +
       +        if((fd = open(file, OREAD)) < 0)
       +                sysfatal("open %s: %r", file);
       +        buf = nil;
       +        tot = 0;
       +        for(;;){
       +                buf = realloc(buf, tot+8192);
       +                if(buf == nil)
       +                        sysfatal("realloc: %r");
       +                if((n = read(fd, buf+tot, 8192)) < 0)
       +                        sysfatal("read: %r");
       +                if(n == 0)
       +                        break;
       +                tot += n;
       +        }
       +
       +        key = asn1toRSApriv(buf, tot);
       +        if(key == nil)
       +                sysfatal("couldn't parse asn1 key");
       +
       +        s = smprint("key proto=rsa %s%ssize=%d ek=%B !dk=%B n=%B !p=%B !q=%B !kp=%B !kq=%B !c2=%B\n",
       +                tag ? tag : "", tag ? " " : "",
       +                mpsignif(key->pub.n), key->pub.ek,
       +                key->dk, key->pub.n, key->p, key->q,
       +                key->kp, key->kq, key->c2);
       +        if(s == nil)
       +                sysfatal("smprint: %r");
       +        write(1, s, strlen(s));
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/dsa2ssh.c b/src/cmd/auth/dsa2ssh.c
       t@@ -0,0 +1,48 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/dsa2ssh [-c comment] [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        DSApriv *k;
       +        char *comment;
       +        uchar buf[8192], *p;
       +        
       +        fmtinstall('B', mpfmt);
       +        fmtinstall('[', encodefmt);
       +        comment = "";
       +        ARGBEGIN{
       +        case 'c':
       +                comment = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc > 1)
       +                usage();
       +
       +        if((k = getdsakey(argc, argv, 0, nil)) == nil)
       +                sysfatal("%r");
       +
       +        p = buf;
       +        p = put4(p, 7);
       +        p = putn(p, "ssh-dss", 7);
       +        p = putmp2(p, k->pub.p);
       +        p = putmp2(p, k->pub.q);
       +        p = putmp2(p, k->pub.alpha);
       +        p = putmp2(p, k->pub.key);
       +        print("ssh-dss %.*[ %s\n", p-buf, buf, comment);
       +        exits(nil);
       +}
   DIR diff --git a/src/cmd/auth/dsagen.c b/src/cmd/auth/dsagen.c
       t@@ -0,0 +1,50 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <mp.h>
       +#include <libsec.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/dsagen [-t 'attr=value attr=value ...']\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char *s;
       +        int bits;
       +        char *tag;
       +        DSApriv *key;
       +
       +        bits = 1024;
       +        tag = nil;
       +        key = nil;
       +        fmtinstall('B', mpfmt);
       +
       +        ARGBEGIN{
       +        case 't':
       +                tag = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 0)
       +                usage();
       +
       +        key = dsagen(nil);
       +
       +        s = smprint("key proto=dsa %s%sp=%B q=%B alpha=%B key=%B !secret=%B\n",
       +                tag ? tag : "", tag ? " " : "",
       +                key->pub.p, key->pub.q, key->pub.alpha, key->pub.key,
       +                key->secret);
       +        if(s == nil)
       +                sysfatal("smprint: %r");
       +
       +        if(write(1, s, strlen(s)) != strlen(s))
       +                sysfatal("write: %r");
       +        
       +        exits(nil);
       +}
   DIR diff --git a/src/cmd/auth/passwd.c b/src/cmd/auth/passwd.c
       t@@ -0,0 +1,153 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <libsec.h>
       +#include <authsrv.h>
       +
       +static char *pbmsg = "AS protocol botch";
       +
       +int
       +asrdresp(int fd, char *buf, int len)
       +{
       +        char error[AERRLEN];
       +
       +        if(read(fd, buf, 1) != 1){
       +                werrstr(pbmsg);
       +                return -1;
       +        }
       +
       +        switch(buf[0]){
       +        case AuthOK:
       +                if(readn(fd, buf, len) < 0){
       +                        werrstr(pbmsg);
       +                        return -1;
       +                }
       +                break;
       +        case AuthErr:
       +                if(readn(fd, error, AERRLEN) < 0){
       +                        werrstr(pbmsg);
       +                        return -1;
       +                }
       +                error[AERRLEN-1] = 0;
       +                werrstr(error);
       +                return -1;
       +        default:
       +                werrstr(pbmsg);
       +                return -1;
       +        }
       +        return 0;
       +}
       +
       +void
       +readln(char *prompt, char *buf, int nbuf, int secret)
       +{
       +        char *p;
       +        
       +        p = readcons(prompt, nil, secret);
       +        if(p == nil)
       +                sysfatal("user terminated input");
       +        if(strlen(p) >= nbuf)
       +                sysfatal("too long");
       +        strcpy(buf, p);
       +        memset(p, 0, strlen(p));
       +        free(p);
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        int fd;
       +        Ticketreq tr;
       +        Ticket t;
       +        Passwordreq pr;
       +        char tbuf[TICKETLEN];
       +        char key[DESKEYLEN];
       +        char buf[512];
       +        char *s, *user;
       +
       +        user = getuser();
       +
       +        ARGBEGIN{
       +        }ARGEND
       +
       +        s = nil;
       +        if(argc > 0){
       +                user = argv[0];
       +                s = strchr(user, '@');
       +                if(s != nil)
       +                        *s++ = 0;
       +                if(*user == 0)
       +                        user = getuser();
       +        }
       +
       +        fd = authdial(nil, s);
       +        if(fd < 0)
       +                sysfatal("protocol botch: %r");
       +
       +        /* send ticket request to AS */
       +        memset(&tr, 0, sizeof(tr));
       +        strcpy(tr.uid, user);
       +        tr.type = AuthPass;
       +        convTR2M(&tr, buf);
       +        if(write(fd, buf, TICKREQLEN) != TICKREQLEN)
       +                sysfatal("protocol botch: %r");
       +        if(asrdresp(fd, buf, TICKETLEN) < 0)
       +                sysfatal("%r");
       +        memmove(tbuf, buf, TICKETLEN);
       +
       +        /*
       +         *  get a password from the user and try to decrypt the
       +         *  ticket.  If it doesn't work we've got a bad password,
       +         *  give up.
       +         */
       +        readln("Plan 9 Password", pr.old, sizeof pr.old, 1);
       +        passtokey(key, pr.old);
       +        convM2T(tbuf, &t, key);
       +        if(t.num != AuthTp || strcmp(t.cuid, tr.uid))
       +                sysfatal("bad password");
       +
       +        /* loop trying new passwords */
       +        for(;;){
       +                pr.changesecret = 0;
       +                *pr.new = 0;
       +                readln("change Plan 9 Password? (y/n)", buf, sizeof buf, 0);
       +                if(*buf == 'y' || *buf == 'Y'){
       +                        readln("Password(8 to 31 characters)", pr.new,
       +                                sizeof pr.new, 1);
       +                        readln("Confirm", buf, sizeof buf, 1);
       +                        if(strcmp(pr.new, buf)){
       +                                print("!mismatch\n");
       +                                continue;
       +                        }
       +                }
       +                readln("change Inferno/POP password? (y/n)", buf, sizeof buf, 0);
       +                if(*buf == 'y' || *buf == 'Y'){
       +                        pr.changesecret = 1;
       +                        readln("make it the same as your plan 9 password? (y/n)",
       +                                buf, sizeof buf, 0);
       +                        if(*buf == 'y' || *buf == 'Y'){
       +                                if(*pr.new == 0)
       +                                        strcpy(pr.secret, pr.old);
       +                                else
       +                                        strcpy(pr.secret, pr.new);
       +                        } else {
       +                                readln("Secret(0 to 256 characters)", pr.secret,
       +                                        sizeof pr.secret, 1);
       +                                readln("Confirm", buf, sizeof buf, 1);
       +                                if(strcmp(pr.secret, buf)){
       +                                        print("!mismatch\n");
       +                                        continue;
       +                                }
       +                        }
       +                }
       +                pr.num = AuthPass;
       +                convPR2M(&pr, buf, t.key);
       +                if(write(fd, buf, PASSREQLEN) != PASSREQLEN)
       +                        sysfatal("AS protocol botch: %r");
       +                if(asrdresp(fd, buf, 0) == 0)
       +                        break;
       +                fprint(2, "refused: %r\n");
       +        }
       +        close(fd);
       +
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/pemdecode.c b/src/cmd/auth/pemdecode.c
       t@@ -0,0 +1,59 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <mp.h>
       +#include <libsec.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "auth/pemdecode section [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char *buf;
       +        uchar *bin;
       +        int fd;
       +        long n, tot;
       +        int len;
       +        char *tag, *file;
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 1 && argc != 2)
       +                usage();
       +
       +        tag = argv[0];
       +        if(argc == 2)
       +                file = argv[1];
       +        else
       +                file = "/dev/stdin";
       +
       +        if((fd = open(file, OREAD)) < 0)
       +                sysfatal("open %s: %r", file);
       +        buf = nil;
       +        tot = 0;
       +        for(;;){
       +                buf = realloc(buf, tot+8192);
       +                if(buf == nil)
       +                        sysfatal("realloc: %r");
       +                if((n = read(fd, buf+tot, 8192)) < 0)
       +                        sysfatal("read: %r");
       +                if(n == 0)
       +                        break;
       +                tot += n;
       +        }
       +        buf[tot] = 0;
       +        bin = decodepem(buf, tag, &len, nil);
       +        if(bin == nil)
       +                sysfatal("cannot extract section '%s' from pem", tag);
       +        if((n=write(1, bin, len)) != len)
       +                sysfatal("writing %d bytes got %ld: %r", len, n);
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/pemencode.c b/src/cmd/auth/pemencode.c
       t@@ -0,0 +1,64 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <mp.h>
       +#include <libsec.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "auth/pemdecode section [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char *buf, *cbuf;
       +        int fd;
       +        long n, tot;
       +        int len;
       +        char *tag, *file;
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 1 && argc != 2)
       +                usage();
       +
       +        tag = argv[0];
       +        if(argc == 2)
       +                file = argv[1];
       +        else
       +                file = "/dev/stdin";
       +
       +        if((fd = open(file, OREAD)) < 0)
       +                sysfatal("open %s: %r", file);
       +        buf = nil;
       +        tot = 0;
       +        for(;;){
       +                buf = realloc(buf, tot+8192);
       +                if(buf == nil)
       +                        sysfatal("realloc: %r");
       +                if((n = read(fd, buf+tot, 8192)) < 0)
       +                        sysfatal("read: %r");
       +                if(n == 0)
       +                        break;
       +                tot += n;
       +        }
       +        buf[tot] = 0;
       +        cbuf = malloc(2*tot);
       +        if(cbuf == nil)
       +                sysfatal("malloc: %r");
       +        len = enc64(cbuf, 2*tot, (uchar*)buf, tot);
       +        print("-----BEGIN %s-----\n", tag);
       +        while(len > 0){
       +                print("%.64s\n", cbuf);
       +                cbuf += 64;
       +                len -= 64;
       +        }
       +        print("-----END %s-----\n", tag);
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/respond.c b/src/cmd/auth/respond.c
       t@@ -0,0 +1,34 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <auth.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/respond 'params' chal\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char buf[128];
       +        int n;
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 2)
       +                usage();
       +
       +        memset(buf, 0, sizeof buf);
       +        n = auth_respond(argv[1], strlen(argv[1]), buf, sizeof buf-1, auth_getkey, "%s", argv[0]);
       +        if(n < 0)
       +                sysfatal("auth_respond: %r");
       +        write(1, buf, n);
       +        print("\n");
       +}
       +
       +        
       +\ No newline at end of file
   DIR diff --git a/src/cmd/auth/rsa2any.c b/src/cmd/auth/rsa2any.c
       t@@ -0,0 +1,303 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +RSApriv*
       +getkey(int argc, char **argv, int needprivate, Attr **pa)
       +{
       +        char *file, *s, *p;
       +        int sz;
       +        RSApriv *key;
       +        Biobuf *b;
       +        int regen;
       +        Attr *a;
       +
       +        if(argc == 0)
       +                file = "/dev/stdin";
       +        else
       +                file = argv[0];
       +
       +        key = mallocz(sizeof(RSApriv), 1);
       +        if(key == nil)
       +                return nil;
       +
       +        if((b = Bopen(file, OREAD)) == nil){
       +                werrstr("open %s: %r", file);
       +                return nil;
       +        }
       +        s = Brdstr(b, '\n', 1);
       +        if(s == nil){
       +                werrstr("read %s: %r", file);
       +                return nil;
       +        }
       +        if(strncmp(s, "key ", 4) != 0){
       +                werrstr("bad key format");
       +                return nil;
       +        }
       +
       +        regen = 0;
       +        a = _parseattr(s+4);
       +        if(a == nil){
       +                werrstr("empty key");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "proto")) == nil){
       +                werrstr("no proto");
       +                return nil;
       +        }
       +        if(strcmp(p, "rsa") != 0){
       +                werrstr("proto not rsa");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "ek")) == nil){
       +                werrstr("no ek");
       +                return nil;
       +        }
       +        if((key->pub.ek = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad ek");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "n")) == nil){
       +                werrstr("no n");
       +                return nil;
       +        }
       +        if((key->pub.n = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad n");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "size")) == nil)
       +                fprint(2, "warning: missing size; will add\n");
       +        else if((sz = strtol(p, &p, 10)) == 0 || *p != 0)
       +                fprint(2, "warning: bad size; will correct\n");
       +        else if(sz != mpsignif(key->pub.n))
       +                fprint(2, "warning: wrong size (got %d, expected %d); will correct\n",
       +                        sz, mpsignif(key->pub.n));
       +        if(!needprivate)
       +                goto call;
       +        if((p = _strfindattr(a, "!dk")) == nil){
       +                werrstr("no !dk");
       +                return nil;
       +        }
       +        if((key->dk = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad !dk");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "!p")) == nil){
       +                werrstr("no !p");
       +                return nil;
       +        }
       +        if((key->p = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad !p");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "!q")) == nil){
       +                werrstr("no !q");
       +                return nil;
       +        }
       +        if((key->q = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad !q");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "!kp")) == nil){
       +                fprint(2, "warning: no !kp\n");
       +                regen = 1;
       +                goto regen;
       +        }
       +        if((key->kp = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                fprint(2, "warning: bad !kp\n");
       +                regen = 1;        
       +                goto regen;
       +        }
       +        if((p = _strfindattr(a, "!kq")) == nil){
       +                fprint(2, "warning: no !kq\n");
       +                regen = 1;        
       +                goto regen;
       +        }
       +        if((key->kq = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                fprint(2, "warning: bad !kq\n");
       +                regen = 1;        
       +                goto regen;
       +        }
       +        if((p = _strfindattr(a, "!c2")) == nil){
       +                fprint(2, "warning: no !c2\n");
       +                regen = 1;        
       +                goto regen;
       +        }
       +        if((key->c2 = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                fprint(2, "warning: bad !c2\n");
       +                regen = 1;        
       +                goto regen;
       +        }
       +regen:
       +        if(regen){
       +                RSApriv *k2;
       +
       +                k2 = rsafill(key->pub.n, key->pub.ek, key->dk, key->p, key->q);
       +                if(k2 == nil){
       +                        werrstr("regenerating chinese-remainder parts failed: %r");
       +                        return nil;
       +                }
       +                key = k2;
       +        }
       +call:
       +        a = _delattr(a, "ek");
       +        a = _delattr(a, "n");
       +        a = _delattr(a, "size");
       +        a = _delattr(a, "!dk");
       +        a = _delattr(a, "!p");
       +        a = _delattr(a, "!q");
       +        a = _delattr(a, "!c2");
       +        a = _delattr(a, "!kp");
       +        a = _delattr(a, "!kq");
       +        if(pa)
       +                *pa = a;
       +        return key;
       +}
       +
       +DSApriv*
       +getdsakey(int argc, char **argv, int needprivate, Attr **pa)
       +{
       +        char *file, *s, *p;
       +        DSApriv *key;
       +        Biobuf *b;
       +        int regen;
       +        Attr *a;
       +
       +        if(argc == 0)
       +                file = "/dev/stdin";
       +        else
       +                file = argv[0];
       +
       +        key = mallocz(sizeof(RSApriv), 1);
       +        if(key == nil)
       +                return nil;
       +
       +        if((b = Bopen(file, OREAD)) == nil){
       +                werrstr("open %s: %r", file);
       +                return nil;
       +        }
       +        s = Brdstr(b, '\n', 1);
       +        if(s == nil){
       +                werrstr("read %s: %r", file);
       +                return nil;
       +        }
       +        if(strncmp(s, "key ", 4) != 0){
       +                werrstr("bad key format");
       +                return nil;
       +        }
       +
       +        regen = 0;
       +        a = _parseattr(s+4);
       +        if(a == nil){
       +                werrstr("empty key");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "proto")) == nil){
       +                werrstr("no proto");
       +                return nil;
       +        }
       +        if(strcmp(p, "dsa") != 0){
       +                werrstr("proto not dsa");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "p")) == nil){
       +                werrstr("no p");
       +                return nil;
       +        }
       +        if((key->pub.p = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad p");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "q")) == nil){
       +                werrstr("no q");
       +                return nil;
       +        }
       +        if((key->pub.q = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad q");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "alpha")) == nil){
       +                werrstr("no alpha");
       +                return nil;
       +        }
       +        if((key->pub.alpha = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad alpha");
       +                return nil;
       +        }
       +        if((p = _strfindattr(a, "key")) == nil){
       +                werrstr("no key=");
       +                return nil;
       +        }
       +        if((key->pub.key = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad key=");
       +                return nil;
       +        }
       +        if(!needprivate)
       +                goto call;
       +        if((p = _strfindattr(a, "!secret")) == nil){
       +                werrstr("no !secret");
       +                return nil;
       +        }
       +        if((key->secret = strtomp(p, &p, 16, nil)) == nil || *p != 0){
       +                werrstr("bad !secret");
       +                return nil;
       +        }
       +call:
       +        a = _delattr(a, "p");
       +        a = _delattr(a, "q");
       +        a = _delattr(a, "alpha");
       +        a = _delattr(a, "key");
       +        a = _delattr(a, "!secret");
       +        if(pa)
       +                *pa = a;
       +        return key;
       +}
       +
       +uchar*
       +put4(uchar *p, uint n)
       +{
       +        p[0] = (n>>24)&0xFF;
       +        p[1] = (n>>16)&0xFF;
       +        p[2] = (n>>8)&0xFF;
       +        p[3] = n&0xFF;
       +        return p+4;
       +}
       +
       +uchar*
       +putn(uchar *p, void *v, uint n)
       +{
       +        memmove(p, v, n);
       +        p += n;
       +        return p;
       +}
       +
       +uchar*
       +putstr(uchar *p, char *s)
       +{
       +        p = put4(p, strlen(s));
       +        p = putn(p, s, strlen(s));
       +        return p;
       +}
       +
       +uchar*
       +putmp2(uchar *p, mpint *b)
       +{
       +        int bits, n;
       +        
       +        if(mpcmp(b, mpzero) == 0)
       +                return put4(p, 0);
       +        bits = mpsignif(b);
       +        n = (bits+7)/8;
       +        if(bits%8 == 0){
       +                p = put4(p, n+1);
       +                *p++ = 0;
       +        }else
       +                p = put4(p, n);
       +        mptobe(b, p, n, nil);
       +        p += n;
       +        return p;
       +}
   DIR diff --git a/src/cmd/auth/rsa2csr.c b/src/cmd/auth/rsa2csr.c
       t@@ -0,0 +1,43 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: aux/rsa2csr 'C=US ...CN=xxx' [key]");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        int len;
       +        uchar *cert;
       +        RSApriv *key;
       +
       +        fmtinstall('B', mpfmt);
       +        fmtinstall('H', encodefmt);
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 1 && argc != 2)
       +                usage();
       +
       +        if((key = getkey(argc-1, argv+1, 1, nil)) == nil)
       +                sysfatal("%r");
       +
       +        cert = X509req(key, argv[0], &len);
       +        if(cert == nil)
       +                sysfatal("X509req: %r");
       +
       +        write(1, cert, len);
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/rsa2pub.c b/src/cmd/auth/rsa2pub.c
       t@@ -0,0 +1,44 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/rsa2pub [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        RSApriv *key;
       +        Attr *a;
       +        char *s;
       +
       +        fmtinstall('A', _attrfmt);
       +        fmtinstall('B', mpfmt);
       +        quotefmtinstall();
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc > 1)
       +                usage();
       +
       +        if((key = getkey(argc, argv, 0, &a)) == nil)
       +                sysfatal("%r");
       +
       +        s = smprint("key %A size=%d ek=%B n=%B\n",
       +                a, 
       +                mpsignif(key->pub.n), key->pub.ek, key->pub.n);
       +        if(s == nil)
       +                sysfatal("smprint: %r");
       +        write(1, s, strlen(s));
       +        exits(nil);
       +}
   DIR diff --git a/src/cmd/auth/rsa2ssh.c b/src/cmd/auth/rsa2ssh.c
       t@@ -0,0 +1,56 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +int ssh2;
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/rsa2ssh [-2] [-c comment] [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        RSApriv *k;
       +        char *comment;
       +        
       +        fmtinstall('B', mpfmt);
       +        fmtinstall('[', encodefmt);
       +        comment = "";
       +        ARGBEGIN{
       +        case '2':
       +                ssh2 = 1;
       +                break;
       +        case 'c':
       +                comment = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc > 1)
       +                usage();
       +
       +        if((k = getkey(argc, argv, 0, nil)) == nil)
       +                sysfatal("%r");
       +
       +        if(ssh2){
       +                uchar buf[8192], *p;
       +                
       +                p = buf;
       +                p = put4(p, 7);
       +                p = putn(p, "ssh-rsa", 7);
       +                p = putmp2(p, k->pub.ek);
       +                p = putmp2(p, k->pub.n);
       +                print("ssh-rsa %.*[ %s\n", p-buf, buf, comment);
       +        }else
       +                print("%d %.10B %.10B %s\n", mpsignif(k->pub.n), k->pub.ek,
       +                        k->pub.n, comment);
       +        exits(nil);
       +}
   DIR diff --git a/src/cmd/auth/rsa2x509.c b/src/cmd/auth/rsa2x509.c
       t@@ -0,0 +1,50 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: aux/rsa2x509 [-e expireseconds] 'C=US ...CN=xxx' [key]");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        int len;
       +        uchar *cert;
       +        ulong valid[2];
       +        RSApriv *key;
       +
       +        fmtinstall('B', mpfmt);
       +        fmtinstall('H', encodefmt);
       +
       +        valid[0] = time(0);
       +        valid[1] = valid[0] + 3*366*24*60*60;
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        case 'e':
       +                valid[1] = valid[0] + strtoul(ARGF(), 0, 10);
       +                break;
       +        }ARGEND
       +
       +        if(argc != 1 && argc != 2)
       +                usage();
       +
       +        if((key = getkey(argc-1, argv+1, 1, nil)) == nil)
       +                sysfatal("%r");
       +
       +        cert = X509gen(key, argv[0], valid, &len);
       +        if(cert == nil)
       +                sysfatal("X509gen: %r");
       +
       +        write(1, cert, len);
       +        exits(0);
       +}
   DIR diff --git a/src/cmd/auth/rsafill.c b/src/cmd/auth/rsafill.c
       t@@ -0,0 +1,46 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <auth.h>
       +#include <mp.h>
       +#include <libsec.h>
       +#include "rsa2any.h"
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/rsafill [file]\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        RSApriv *key;
       +        Attr *a;
       +        char *s;
       +
       +        fmtinstall('A', _attrfmt);
       +        fmtinstall('B', mpfmt);
       +        quotefmtinstall();
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc > 1)
       +                usage();
       +
       +        if((key = getkey(argc, argv, 1, &a)) == nil)
       +                sysfatal("%r");
       +
       +        s = smprint("key %A size=%d ek=%B !dk=%B n=%B !p=%B !q=%B !kp=%B !kq=%B !c2=%B\n",
       +                a, 
       +                mpsignif(key->pub.n), key->pub.ek,
       +                key->dk, key->pub.n, key->p, key->q,
       +                key->kp, key->kq, key->c2);
       +        if(s == nil)
       +                sysfatal("smprint: %r");
       +        write(1, s, strlen(s));
       +        exits(nil);
       +}
   DIR diff --git a/src/cmd/auth/rsagen.c b/src/cmd/auth/rsagen.c
       t@@ -0,0 +1,60 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <mp.h>
       +#include <libsec.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/rsagen [-b bits] [-t 'attr=value attr=value ...']\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        char *s;
       +        int bits;
       +        char *tag;
       +        RSApriv *key;
       +
       +        bits = 1024;
       +        tag = nil;
       +        key = nil;
       +        fmtinstall('B', mpfmt);
       +
       +        ARGBEGIN{
       +        case 'b':
       +                bits = atoi(EARGF(usage()));
       +                if(bits == 0)
       +                        usage();
       +                break;
       +        case 't':
       +                tag = EARGF(usage());
       +                break;
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 0)
       +                usage();
       +
       +        do{
       +                if(key)
       +                        rsaprivfree(key);
       +                key = rsagen(bits, 6, 0);
       +        }while(mpsignif(key->pub.n) != bits);
       +
       +        s = smprint("key proto=rsa %s%ssize=%d ek=%B !dk=%B n=%B !p=%B !q=%B !kp=%B !kq=%B !c2=%B\n",
       +                tag ? tag : "", tag ? " " : "",
       +                mpsignif(key->pub.n), key->pub.ek,
       +                key->dk, key->pub.n, key->p, key->q,
       +                key->kp, key->kq, key->c2);
       +        if(s == nil)
       +                sysfatal("smprint: %r");
       +
       +        if(write(1, s, strlen(s)) != strlen(s))
       +                sysfatal("write: %r");
       +        
       +        exits(nil);
       +}
   DIR diff --git a/src/cmd/auth/userpasswd.c b/src/cmd/auth/userpasswd.c
       t@@ -0,0 +1,34 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <auth.h>
       +
       +void
       +usage(void)
       +{
       +        fprint(2, "usage: auth/userpasswd fmt\n");
       +        exits("usage");
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        UserPasswd *up;
       +
       +        ARGBEGIN{
       +        default:
       +                usage();
       +        }ARGEND
       +
       +        if(argc != 1)
       +                usage();
       +
       +        up = auth_getuserpasswd(auth_getkey, "proto=pass %s", argv[0]);
       +        if(up == nil)        /* bug in factotum, fixed but need to reboot servers -rsc, 2/10/2002 */
       +                up = auth_getuserpasswd(nil, "proto=pass %s", argv[0]);
       +        if(up == nil)
       +                sysfatal("getuserpasswd: %r");
       +
       +        quotefmtinstall();
       +        print("%s\n%s\n", up->user, up->passwd);
       +        exits(0);
       +}