ref: 464763202be7bdafa703c8c2ecfe1f4a5142f26f
parent: 21aee5d8cbd1ebae796cdc58404b8d8902738370
author: cinap_lenrek <[email protected]>
date: Mon Apr 11 16:23:34 EDT 2016
ape: add libauth, libbio, libmp and libsec as replacements for openssl
--- /dev/null
+++ b/sys/include/ape/auth.h
@@ -1,0 +1,155 @@
+#ifndef _PLAN9_SOURCE
+ This header file is an extension to ANSI/POSIX
+#endif
+
+#ifndef __AUTH_H_
+#define __AUTH_H_
+
+#pragma src "/sys/src/ape/lib/auth"
+#pragma lib "/$M/lib/ape/libauth.a"
+
+#include <u.h>
+#include <fmt.h>
+
+/*
+ * Interface for typical callers.
+ */
+
+typedef struct AuthInfo AuthInfo;
+typedef struct Chalstate Chalstate;
+typedef struct Chapreply Chapreply;
+typedef struct MSchapreply MSchapreply;
+typedef struct UserPasswd UserPasswd;
+typedef struct AuthRpc AuthRpc;
+
+enum
+{
+ MAXCHLEN= 256, /* max challenge length */
+ MAXNAMELEN= 256, /* maximum name length */
+ MD5LEN= 16,
+
+ ARok = 0, /* rpc return values */
+ ARdone,
+ ARerror,
+ ARneedkey,
+ ARbadkey,
+ ARwritenext,
+ ARtoosmall,
+ ARtoobig,
+ ARrpcfailure,
+ ARphase,
+
+ AuthRpcMax = 4096,
+};
+
+struct AuthRpc
+{
+ int afd;
+ char ibuf[AuthRpcMax+1]; /* +1 for NUL in auth_rpc.c */
+ char obuf[AuthRpcMax];
+ char *arg;
+ uint narg;
+};
+
+struct AuthInfo
+{
+ char *cuid; /* caller id */
+ char *suid; /* server id */
+ char *cap; /* capability (only valid on server side) */
+ int nsecret; /* length of secret */
+ uchar *secret; /* secret */
+};
+
+struct Chalstate
+{
+ char *user;
+ char chal[MAXCHLEN];
+ int nchal;
+ void *resp;
+ int nresp;
+
+/* for implementation only */
+ int afd; /* to factotum */
+ AuthRpc *rpc; /* to factotum */
+ char userbuf[MAXNAMELEN]; /* temp space if needed */
+ int userinchal; /* user was sent to obtain challenge */
+};
+
+struct Chapreply /* for protocol "chap" */
+{
+ uchar id;
+ char resp[MD5LEN];
+};
+
+struct MSchapreply /* for protocol "mschap" */
+{
+ char LMresp[24]; /* Lan Manager response */
+ char NTresp[24]; /* NT response */
+};
+
+struct UserPasswd
+{
+ char *user;
+ char *passwd;
+};
+
+extern int newns(char*, char*);
+extern int addns(char*, char*);
+
+extern int noworld(char*);
+extern int amount(int, char*, int, char*);
+
+/* these two may get generalized away -rsc */
+extern int login(char*, char*, char*);
+extern int httpauth(char*, char*);
+
+typedef struct Attr Attr;
+enum {
+ AttrNameval, /* name=val -- when matching, must have name=val */
+ AttrQuery, /* name? -- when matching, must be present */
+ AttrDefault, /* name:=val -- when matching, if present must match INTERNAL */
+};
+struct Attr
+{
+ int type;
+ Attr *next;
+ char *name;
+ char *val;
+};
+
+typedef int AuthGetkey(char*);
+
+int _attrfmt(Fmt*);
+Attr *_copyattr(Attr*);
+Attr *_delattr(Attr*, char*);
+Attr *_findattr(Attr*, char*);
+void _freeattr(Attr*);
+Attr *_mkattr(int, char*, char*, Attr*);
+Attr *_parseattr(char*);
+char *_strfindattr(Attr*, char*);
+#pragma varargck type "A" Attr*
+
+extern AuthInfo* fauth_proxy(int, AuthRpc *rpc, AuthGetkey *getkey, char *params);
+extern AuthInfo* auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...);
+extern int auth_getkey(char*);
+extern int (*amount_getkey)(char*);
+extern void auth_freeAI(AuthInfo *ai);
+extern int auth_chuid(AuthInfo *ai, char *ns);
+extern Chalstate *auth_challenge(char*, ...);
+extern AuthInfo* auth_response(Chalstate*);
+extern int auth_respond(void*, uint, char*, uint, void*, uint, AuthGetkey *getkey, char*, ...);
+extern void auth_freechal(Chalstate*);
+extern AuthInfo* auth_userpasswd(char *user, char *passwd);
+extern UserPasswd* auth_getuserpasswd(AuthGetkey *getkey, char*, ...);
+extern AuthInfo* auth_getinfo(AuthRpc *rpc);
+extern AuthRpc* auth_allocrpc(int afd);
+extern Attr* auth_attr(AuthRpc *rpc);
+extern void auth_freerpc(AuthRpc *rpc);
+extern uint auth_rpc(AuthRpc *rpc, char *verb, void *a, int n);
+extern int auth_wep(char*, char*, ...);
+#pragma varargck argpos auth_proxy 3
+#pragma varargck argpos auth_challenge 1
+#pragma varargck argpos auth_respond 8
+#pragma varargck argpos auth_getuserpasswd 2
+
+#endif
--- /dev/null
+++ b/sys/include/ape/bio.h
@@ -1,0 +1,89 @@
+#ifndef _PLAN9_SOURCE
+ This header file is an extension to ANSI/POSIX
+#endif
+
+#ifndef __BIO_H_
+#define __BIO_H_
+#pragma src "/sys/src/libbio"
+#pragma lib "/$M/lib/ape/libbio.a"
+
+#include <u.h>
+
+typedef struct Biobuf Biobuf;
+typedef struct Biobufhdr Biobufhdr;
+
+enum
+{
+ Bsize = 8*1024,
+ Bungetsize = UTFmax+1, /* space for ungetc */
+ Bmagic = 0x314159,
+ Beof = -1,
+ Bbad = -2,
+
+ Binactive = 0, /* states */
+ Bractive,
+ Bwactive,
+ Bracteof,
+};
+
+struct Biobufhdr
+{
+ int icount; /* neg num of bytes at eob */
+ int ocount; /* num of bytes at bob */
+ int rdline; /* num of bytes after rdline */
+ int runesize; /* num of bytes of last getrune */
+ int state; /* r/w/inactive */
+ int fid; /* open file */
+ int flag; /* magic if malloc'ed */
+ vlong offset; /* offset of buffer in file */
+ int bsize; /* size of buffer */
+ uchar* bbuf; /* pointer to beginning of buffer */
+ uchar* ebuf; /* pointer to end of buffer */
+ uchar* gbuf; /* pointer to good data in buf */
+ void (*errorf)(char *); /* called on error if not nil */
+};
+
+struct Biobuf
+{
+ Biobufhdr;
+ uchar b[Bungetsize+Bsize];
+};
+
+/* Dregs, redefined as functions for backwards compatibility */
+#define BGETC(bp) Bgetc(bp)
+#define BPUTC(bp,c) Bputc(bp,c)
+#define BOFFSET(bp) Boffset(bp)
+#define BLINELEN(bp) Blinelen(bp)
+#define BFILDES(bp) Bfildes(bp)
+
+int Bbuffered(Biobufhdr*);
+int Bfildes(Biobufhdr*);
+int Bflush(Biobufhdr*);
+int Bgetc(Biobufhdr*);
+int Bgetd(Biobufhdr*, double*);
+long Bgetrune(Biobufhdr*);
+int Binit(Biobuf*, int, int);
+int Binits(Biobufhdr*, int, int, uchar*, int);
+int Blinelen(Biobufhdr*);
+vlong Boffset(Biobufhdr*);
+Biobuf* Bopen(char*, int);
+Biobuf* Bfdopen(int, int);
+int Bprint(Biobufhdr*, char*, ...);
+int Bvprint(Biobufhdr*, char*, va_list);
+int Bputc(Biobufhdr*, int);
+int Bputrune(Biobufhdr*, long);
+void* Brdline(Biobufhdr*, int);
+char* Brdstr(Biobufhdr*, int, int);
+long Bread(Biobufhdr*, void*, long);
+vlong Bseek(Biobufhdr*, vlong, int);
+int Bterm(Biobufhdr*);
+int Bungetc(Biobufhdr*);
+int Bungetrune(Biobufhdr*);
+long Bwrite(Biobufhdr*, void*, long);
+void Blethal(Biobufhdr*, void(*)(char*));
+void Berror(Biobufhdr*, char*, ...);
+
+#pragma varargck argpos Bprint 2
+#pragma varargck argpos Berror 2
+
+#endif
--- /dev/null
+++ b/sys/include/ape/libsec.h
@@ -1,0 +1,584 @@
+#ifndef _PLAN9_SOURCE
+ This header file is an extension to ANSI/POSIX
+#endif
+
+#ifndef __LIBSEC_H_
+#define __LIBSEC_H_
+
+#pragma src "/sys/src/ape/lib/sec"
+#pragma lib "/$M/lib/ape/libsec.a"
+
+#include <u.h>
+
+#ifndef _MPINT
+typedef struct mpint mpint;
+#endif
+
+/*
+ * AES definitions
+ */
+
+enum
+{
+ AESbsize= 16,
+ AESmaxkey= 32,
+ AESmaxrounds= 14
+};
+
+typedef struct AESstate AESstate;
+struct AESstate
+{
+ ulong setup;
+ int rounds;
+ int keybytes;
+ uchar key[AESmaxkey]; /* unexpanded key */
+ ulong ekey[4*(AESmaxrounds + 1)]; /* encryption key */
+ ulong dkey[4*(AESmaxrounds + 1)]; /* decryption key */
+ uchar ivec[AESbsize]; /* initialization vector */
+ uchar mackey[3 * AESbsize]; /* 3 XCBC mac 96 keys */
+};
+
+/* block ciphers */
+void aes_encrypt(ulong rk[], int Nr, uchar pt[16], uchar ct[16]);
+void aes_decrypt(ulong rk[], int Nr, uchar ct[16], uchar pt[16]);
+
+void setupAESstate(AESstate *s, uchar key[], int keybytes, uchar *ivec);
+void aesCBCencrypt(uchar *p, int len, AESstate *s);
+void aesCBCdecrypt(uchar *p, int len, AESstate *s);
+
+void setupAESXCBCstate(AESstate *s);
+uchar* aesXCBCmac(uchar *p, int len, AESstate *s);
+
+typedef struct AESGCMstate AESGCMstate;
+struct AESGCMstate
+{
+ AESstate;
+
+ ulong H[4];
+ ulong M[16][256][4];
+};
+
+void setupAESGCMstate(AESGCMstate *s, uchar *key, int keylen, uchar *iv, int ivlen);
+void aesgcm_setiv(AESGCMstate *s, uchar *iv, int ivlen);
+void aesgcm_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], AESGCMstate *s);
+int aesgcm_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], AESGCMstate *s);
+
+/*
+ * Blowfish Definitions
+ */
+
+enum
+{
+ BFbsize = 8,
+ BFrounds= 16
+};
+
+/* 16-round Blowfish */
+typedef struct BFstate BFstate;
+struct BFstate
+{
+ ulong setup;
+
+ uchar key[56];
+ uchar ivec[8];
+
+ u32int pbox[BFrounds+2];
+ u32int sbox[1024];
+};
+
+void setupBFstate(BFstate *s, uchar key[], int keybytes, uchar *ivec);
+void bfCBCencrypt(uchar*, int, BFstate*);
+void bfCBCdecrypt(uchar*, int, BFstate*);
+void bfECBencrypt(uchar*, int, BFstate*);
+void bfECBdecrypt(uchar*, int, BFstate*);
+
+/*
+ * Chacha definitions
+ */
+
+enum
+{
+ ChachaBsize= 64,
+ ChachaKeylen= 256/8,
+ ChachaIVlen= 96/8,
+};
+
+typedef struct Chachastate Chachastate;
+struct Chachastate
+{
+ union{
+ u32int input[16];
+ struct {
+ u32int constant[4];
+ u32int key[8];
+ u32int counter;
+ u32int iv[3];
+ };
+ };
+ int rounds;
+ int ivwords;
+};
+
+void setupChachastate(Chachastate*, uchar*, ulong, uchar*, ulong, int);
+void chacha_setiv(Chachastate *, uchar*);
+void chacha_setblock(Chachastate*, u64int);
+void chacha_encrypt(uchar*, ulong, Chachastate*);
+void chacha_encrypt2(uchar*, uchar*, ulong, Chachastate*);
+
+void ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
+int ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
+
+/*
+ * Salsa definitions
+ */
+enum
+{
+ SalsaBsize= 64,
+ SalsaKeylen= 256/8,
+ SalsaIVlen= 64/8,
+ XSalsaIVlen= 192/8,
+};
+
+typedef struct Salsastate Salsastate;
+struct Salsastate
+{
+ u32int input[16];
+ u32int key[8];
+ int rounds;
+ int ivwords;
+};
+
+void setupSalsastate(Salsastate*, uchar*, ulong, uchar*, ulong, int);
+void salsa_setiv(Salsastate*, uchar*);
+void salsa_setblock(Salsastate*, u64int);
+void salsa_encrypt(uchar*, ulong, Salsastate*);
+void salsa_encrypt2(uchar*, uchar*, ulong, Salsastate*);
+
+void hsalsa(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds);
+
+/*
+ * DES definitions
+ */
+
+enum
+{
+ DESbsize= 8
+};
+
+/* single des */
+typedef struct DESstate DESstate;
+struct DESstate
+{
+ ulong setup;
+ uchar key[8]; /* unexpanded key */
+ ulong expanded[32]; /* expanded key */
+ uchar ivec[8]; /* initialization vector */
+};
+
+void setupDESstate(DESstate *s, uchar key[8], uchar *ivec);
+void des_key_setup(uchar[8], ulong[32]);
+void block_cipher(ulong*, uchar*, int);
+void desCBCencrypt(uchar*, int, DESstate*);
+void desCBCdecrypt(uchar*, int, DESstate*);
+void desECBencrypt(uchar*, int, DESstate*);
+void desECBdecrypt(uchar*, int, DESstate*);
+
+/* for backward compatibility with 7-byte DES key format */
+void des56to64(uchar *k56, uchar *k64);
+void des64to56(uchar *k64, uchar *k56);
+void key_setup(uchar[7], ulong[32]);
+
+/* triple des encrypt/decrypt orderings */
+enum {
+ DES3E= 0,
+ DES3D= 1,
+ DES3EEE= 0,
+ DES3EDE= 2,
+ DES3DED= 5,
+ DES3DDD= 7
+};
+
+typedef struct DES3state DES3state;
+struct DES3state
+{
+ ulong setup;
+ uchar key[3][8]; /* unexpanded key */
+ ulong expanded[3][32]; /* expanded key */
+ uchar ivec[8]; /* initialization vector */
+};
+
+void setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec);
+void triple_block_cipher(ulong keys[3][32], uchar*, int);
+void des3CBCencrypt(uchar*, int, DES3state*);
+void des3CBCdecrypt(uchar*, int, DES3state*);
+void des3ECBencrypt(uchar*, int, DES3state*);
+void des3ECBdecrypt(uchar*, int, DES3state*);
+
+/*
+ * digests
+ */
+
+enum
+{
+ SHA1dlen= 20, /* SHA digest length */
+ SHA2_224dlen= 28, /* SHA-224 digest length */
+ SHA2_256dlen= 32, /* SHA-256 digest length */
+ SHA2_384dlen= 48, /* SHA-384 digest length */
+ SHA2_512dlen= 64, /* SHA-512 digest length */
+ MD4dlen= 16, /* MD4 digest length */
+ MD5dlen= 16, /* MD5 digest length */
+ Poly1305dlen= 16, /* Poly1305 digest length */
+
+ Hmacblksz = 64, /* in bytes; from rfc2104 */
+};
+
+typedef struct DigestState DigestState;
+struct DigestState
+{
+ uvlong len;
+ union {
+ u32int state[16];
+ u64int bstate[8];
+ };
+ uchar buf[256];
+ int blen;
+ char malloced;
+ char seeded;
+};
+typedef struct DigestState SHAstate; /* obsolete name */
+typedef struct DigestState SHA1state;
+typedef struct DigestState SHA2_224state;
+typedef struct DigestState SHA2_256state;
+typedef struct DigestState SHA2_384state;
+typedef struct DigestState SHA2_512state;
+typedef struct DigestState MD5state;
+typedef struct DigestState MD4state;
+
+DigestState* md4(uchar*, ulong, uchar*, DigestState*);
+DigestState* md5(uchar*, ulong, uchar*, DigestState*);
+DigestState* sha1(uchar*, ulong, uchar*, DigestState*);
+DigestState* sha2_224(uchar*, ulong, uchar*, DigestState*);
+DigestState* sha2_256(uchar*, ulong, uchar*, DigestState*);
+DigestState* sha2_384(uchar*, ulong, uchar*, DigestState*);
+DigestState* sha2_512(uchar*, ulong, uchar*, DigestState*);
+DigestState* hmac_x(uchar *p, ulong len, uchar *key, ulong klen,
+ uchar *digest, DigestState *s,
+ DigestState*(*x)(uchar*, ulong, uchar*, DigestState*),
+ int xlen);
+DigestState* hmac_md5(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+DigestState* hmac_sha1(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+DigestState* hmac_sha2_224(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+DigestState* hmac_sha2_256(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+DigestState* hmac_sha2_384(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+DigestState* hmac_sha2_512(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+char* md5pickle(MD5state*);
+MD5state* md5unpickle(char*);
+char* sha1pickle(SHA1state*);
+SHA1state* sha1unpickle(char*);
+
+DigestState* poly1305(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+
+/*
+ * random number generation
+ */
+void genrandom(uchar *buf, int nbytes);
+void prng(uchar *buf, int nbytes);
+ulong fastrand(void);
+ulong nfastrand(ulong);
+
+/*
+ * primes
+ */
+void genprime(mpint *p, int n, int accuracy); /* generate n-bit probable prime */
+void gensafeprime(mpint *p, mpint *alpha, int n, int accuracy); /* prime & generator */
+void genstrongprime(mpint *p, int n, int accuracy); /* generate n-bit strong prime */
+void DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen]);
+int probably_prime(mpint *n, int nrep); /* miller-rabin test */
+int smallprimetest(mpint *p); /* returns -1 if not prime, 0 otherwise */
+
+/*
+ * rc4
+ */
+typedef struct RC4state RC4state;
+struct RC4state
+{
+ uchar state[256];
+ uchar x;
+ uchar y;
+};
+
+void setupRC4state(RC4state*, uchar*, int);
+void rc4(RC4state*, uchar*, int);
+void rc4skip(RC4state*, int);
+void rc4back(RC4state*, int);
+
+/*
+ * rsa
+ */
+typedef struct RSApub RSApub;
+typedef struct RSApriv RSApriv;
+typedef struct PEMChain PEMChain;
+
+/* public/encryption key */
+struct RSApub
+{
+ mpint *n; /* modulus */
+ mpint *ek; /* exp (encryption key) */
+};
+
+/* private/decryption key */
+struct RSApriv
+{
+ RSApub pub;
+
+ mpint *dk; /* exp (decryption key) */
+
+ /* precomputed values to help with chinese remainder theorem calc */
+ mpint *p;
+ mpint *q;
+ mpint *kp; /* dk mod p-1 */
+ mpint *kq; /* dk mod q-1 */
+ mpint *c2; /* (inv p) mod q */
+};
+
+struct PEMChain{
+ PEMChain*next;
+ uchar *pem;
+ int pemlen;
+};
+
+RSApriv* rsagen(int nlen, int elen, int rounds);
+RSApriv* rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q);
+mpint* rsaencrypt(RSApub *k, mpint *in, mpint *out);
+mpint* rsadecrypt(RSApriv *k, mpint *in, mpint *out);
+RSApub* rsapuballoc(void);
+void rsapubfree(RSApub*);
+RSApriv* rsaprivalloc(void);
+void rsaprivfree(RSApriv*);
+RSApub* rsaprivtopub(RSApriv*);
+RSApub* X509toRSApub(uchar*, int, char*, int);
+RSApriv* asn1toRSApriv(uchar*, int);
+void asn1dump(uchar *der, int len);
+uchar* decodePEM(char *s, char *type, int *len, char **new_s);
+PEMChain* decodepemchain(char *s, char *type);
+uchar* X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
+uchar* X509rsareq(RSApriv *priv, char *subj, int *certlen);
+char* X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk);
+char* X509rsaverify(uchar *cert, int ncert, RSApub *pk);
+
+void X509dump(uchar *cert, int ncert);
+
+/*
+ * elgamal
+ */
+typedef struct EGpub EGpub;
+typedef struct EGpriv EGpriv;
+typedef struct EGsig EGsig;
+
+/* public/encryption key */
+struct EGpub
+{
+ mpint *p; /* modulus */
+ mpint *alpha; /* generator */
+ mpint *key; /* (encryption key) alpha**secret mod p */
+};
+
+/* private/decryption key */
+struct EGpriv
+{
+ EGpub pub;
+ mpint *secret; /* (decryption key) */
+};
+
+/* signature */
+struct EGsig
+{
+ mpint *r, *s;
+};
+
+EGpriv* eggen(int nlen, int rounds);
+mpint* egencrypt(EGpub *k, mpint *in, mpint *out); /* deprecated */
+mpint* egdecrypt(EGpriv *k, mpint *in, mpint *out);
+EGsig* egsign(EGpriv *k, mpint *m);
+int egverify(EGpub *k, EGsig *sig, mpint *m);
+EGpub* egpuballoc(void);
+void egpubfree(EGpub*);
+EGpriv* egprivalloc(void);
+void egprivfree(EGpriv*);
+EGsig* egsigalloc(void);
+void egsigfree(EGsig*);
+EGpub* egprivtopub(EGpriv*);
+
+/*
+ * dsa
+ */
+typedef struct DSApub DSApub;
+typedef struct DSApriv DSApriv;
+typedef struct DSAsig DSAsig;
+
+/* public/encryption key */
+struct DSApub
+{
+ mpint *p; /* modulus */
+ mpint *q; /* group order, q divides p-1 */
+ mpint *alpha; /* group generator */
+ mpint *key; /* (encryption key) alpha**secret mod p */
+};
+
+/* private/decryption key */
+struct DSApriv
+{
+ DSApub pub;
+ mpint *secret; /* (decryption key) */
+};
+
+/* signature */
+struct DSAsig
+{
+ mpint *r, *s;
+};
+
+DSApriv* dsagen(DSApub *opub); /* opub not checked for consistency! */
+DSAsig* dsasign(DSApriv *k, mpint *m);
+int dsaverify(DSApub *k, DSAsig *sig, mpint *m);
+DSApub* dsapuballoc(void);
+void dsapubfree(DSApub*);
+DSApriv* dsaprivalloc(void);
+void dsaprivfree(DSApriv*);
+DSAsig* dsasigalloc(void);
+void dsasigfree(DSAsig*);
+DSApub* dsaprivtopub(DSApriv*);
+DSApriv* asn1toDSApriv(uchar*, int);
+
+/*
+ * TLS
+ */
+typedef struct Thumbprint{
+ struct Thumbprint *next;
+ uchar sha1[SHA1dlen];
+} Thumbprint;
+
+typedef struct TLSconn{
+ char dir[40]; /* connection directory */
+ uchar *cert; /* certificate (local on input, remote on output) */
+ uchar *sessionID;
+ uchar *psk;
+ int certlen;
+ int sessionIDlen;
+ int psklen;
+ int (*trace)(char*fmt, ...);
+ PEMChain*chain; /* optional extra certificate evidence for servers to present */
+ char *sessionType;
+ uchar *sessionKey;
+ int sessionKeylen;
+ char *sessionConst;
+ char *serverName;
+ char *pskID;
+} TLSconn;
+
+/* tlshand.c */
+int tlsClient(int fd, TLSconn *c);
+int tlsServer(int fd, TLSconn *c);
+
+/* thumb.c */
+Thumbprint* initThumbprints(char *ok, char *crl);
+void freeThumbprints(Thumbprint *ok);
+int okThumbprint(uchar *sha1, Thumbprint *ok);
+
+/* readcert.c */
+uchar *readcert(char *filename, int *pcertlen);
+PEMChain*readcertchain(char *filename);
+
+/* aes_xts.c */
+int aes_xts_encrypt(ulong tweak[], ulong ecb[], vlong sectorNumber, uchar *input, uchar *output, ulong len) ;
+int aes_xts_decrypt(ulong tweak[], ulong ecb[], vlong sectorNumber, uchar *input, uchar *output, ulong len);
+
+typedef struct ECpoint{
+ int inf;
+ mpint *x;
+ mpint *y;
+} ECpoint;
+
+typedef ECpoint ECpub;
+typedef struct ECpriv{
+ ECpoint;
+ mpint *d;
+} ECpriv;
+
+typedef struct ECdomain{
+ mpint *p;
+ mpint *a;
+ mpint *b;
+ ECpoint G;
+ mpint *n;
+ mpint *h;
+} ECdomain;
+
+void ecdominit(ECdomain *, void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h));
+void ecdomfree(ECdomain *);
+
+void ecassign(ECdomain *, ECpoint *old, ECpoint *new);
+void ecadd(ECdomain *, ECpoint *a, ECpoint *b, ECpoint *s);
+void ecmul(ECdomain *, ECpoint *a, mpint *k, ECpoint *s);
+ECpoint* strtoec(ECdomain *, char *, char **, ECpoint *);
+ECpriv* ecgen(ECdomain *, ECpriv*);
+int ecverify(ECdomain *, ECpoint *);
+int ecpubverify(ECdomain *, ECpub *);
+void ecdsasign(ECdomain *, ECpriv *, uchar *, int, mpint *, mpint *);
+int ecdsaverify(ECdomain *, ECpub *, uchar *, int, mpint *, mpint *);
+void base58enc(uchar *, char *, int);
+int base58dec(char *, uchar *, int);
+
+ECpub* ecdecodepub(ECdomain *dom, uchar *, int);
+int ecencodepub(ECdomain *dom, ECpub *, uchar *, int);
+void ecpubfree(ECpub *);
+
+ECpub* X509toECpub(uchar *cert, int ncert, ECdomain *dom);
+char* X509ecdsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, ECdomain *dom, ECpub *pub);
+char* X509ecdsaverify(uchar *sig, int siglen, ECdomain *dom, ECpub *pub);
+
+/* curves */
+void secp256r1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
+void secp256k1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
+
+DigestState* ripemd160(uchar *, ulong, uchar *, DigestState *);
+
+/*
+ * Diffie-Hellman key exchange
+ */
+
+typedef struct DHstate DHstate;
+struct DHstate
+{
+ mpint *g; /* base g */
+ mpint *p; /* large prime */
+ mpint *q; /* subgroup prime */
+ mpint *x; /* random secret */
+ mpint *y; /* public key y = g**x % p */
+};
+
+/* generate new public key: y = g**x % p */
+mpint* dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g);
+
+/* calculate shared key: k = y**x % p */
+mpint* dh_finish(DHstate *dh, mpint *y);
+
+/* Curve25519 elliptic curve, public key function */
+void curve25519(uchar mypublic[32], uchar secret[32], uchar basepoint[32]);
+
+/* Curve25519 diffie hellman */
+void curve25519_dh_new(uchar x[32], uchar y[32]);
+void curve25519_dh_finish(uchar x[32], uchar y[32], uchar z[32]);
+
+/* password-based key derivation function 2 (rfc2898) */
+void pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen,
+ DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen);
+
+/* hmac-based key derivation function (rfc5869) */
+void hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo, uchar *key, ulong nkey, uchar *d, ulong dlen,
+ DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen);
+
+/* timing safe memcmp() */
+int tsmemcmp(void*, void*, ulong);
+
+#endif
--- /dev/null
+++ b/sys/include/ape/mp.h
@@ -1,0 +1,196 @@
+#ifndef _PLAN9_SOURCE
+ This header file is an extension to ANSI/POSIX
+#endif
+
+#ifndef __LIBMP_H_
+#define __LIBMP_H_
+
+#pragma src "/sys/src/ape/lib/mp"
+#pragma lib "/$M/lib/ape/libmp.a"
+
+#include <u.h>
+#include <fmt.h>
+
+typedef unsigned int mpdigit; /* from /$objtype/include/u.h */
+
+#define _MPINT 1
+
+/*
+ * the code assumes mpdigit to be at least an int
+ * mpdigit must be an atomic type. mpdigit is defined
+ * in the architecture specific u.h
+ */
+typedef struct mpint mpint;
+
+struct mpint
+{
+ int sign; /* +1 or -1 */
+ int size; /* allocated digits */
+ int top; /* significant digits */
+ mpdigit *p;
+ char flags;
+};
+
+enum
+{
+ MPstatic= 0x01, /* static constant */
+ MPnorm= 0x02, /* normalization status */
+ MPtimesafe= 0x04, /* request time invariant computation */
+ MPfield= 0x08, /* this mpint is a field modulus */
+
+ Dbytes= sizeof(mpdigit), /* bytes per digit */
+ Dbits= Dbytes*8 /* bits per digit */
+};
+
+/* allocation */
+void mpsetminbits(int n); /* newly created mpint's get at least n bits */
+mpint* mpnew(int n); /* create a new mpint with at least n bits */
+void mpfree(mpint *b);
+void mpbits(mpint *b, int n); /* ensure that b has at least n bits */
+mpint* mpnorm(mpint *b); /* dump leading zeros */
+mpint* mpcopy(mpint *b);
+void mpassign(mpint *old, mpint *new);
+
+/* random bits */
+mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b);
+/* return uniform random [0..n-1] */
+mpint* mpnrand(mpint *n, void (*gen)(uchar*, int), mpint *b);
+
+/* conversion */
+mpint* strtomp(char*, char**, int, mpint*); /* ascii */
+int mpfmt(Fmt*);
+char* mptoa(mpint*, int, char*, int);
+mpint* letomp(uchar*, uint, mpint*); /* byte array, little-endian */
+int mptole(mpint*, uchar*, uint, uchar**);
+void mptolel(mpint *b, uchar *p, int n);
+mpint* betomp(uchar*, uint, mpint*); /* byte array, big-endian */
+int mptobe(mpint*, uchar*, uint, uchar**);
+void mptober(mpint *b, uchar *p, int n);
+uint mptoui(mpint*); /* unsigned int */
+mpint* uitomp(uint, mpint*);
+int mptoi(mpint*); /* int */
+mpint* itomp(int, mpint*);
+uvlong mptouv(mpint*); /* unsigned vlong */
+mpint* uvtomp(uvlong, mpint*);
+vlong mptov(mpint*); /* vlong */
+mpint* vtomp(vlong, mpint*);
+
+/* divide 2 digits by one */
+void mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
+
+/* in the following, the result mpint may be */
+/* the same as one of the inputs. */
+void mpadd(mpint *b1, mpint *b2, mpint *sum); /* sum = b1+b2 */
+void mpsub(mpint *b1, mpint *b2, mpint *diff); /* diff = b1-b2 */
+void mpleft(mpint *b, int shift, mpint *res); /* res = b<<shift */
+void mpright(mpint *b, int shift, mpint *res); /* res = b>>shift */
+void mpmul(mpint *b1, mpint *b2, mpint *prod); /* prod = b1*b2 */
+void mpexp(mpint *b, mpint *e, mpint *m, mpint *res); /* res = b**e mod m */
+void mpmod(mpint *b, mpint *m, mpint *remainder); /* remainder = b mod m */
+
+/* logical operations */
+void mpand(mpint *b1, mpint *b2, mpint *res);
+void mpbic(mpint *b1, mpint *b2, mpint *res);
+void mpor(mpint *b1, mpint *b2, mpint *res);
+void mpnot(mpint *b, mpint *res);
+void mpxor(mpint *b1, mpint *b2, mpint *res);
+void mptrunc(mpint *b, int n, mpint *res);
+void mpxtend(mpint *b, int n, mpint *res);
+
+/* modular arithmetic, time invariant when 0≤b1≤m-1 and 0≤b2≤m-1 */
+void mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum); /* sum = b1+b2 % m */
+void mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff); /* diff = b1-b2 % m */
+void mpmodmul(mpint *b1, mpint *b2, mpint *m, mpint *prod); /* prod = b1*b2 % m */
+
+/* quotient = dividend/divisor, remainder = dividend % divisor */
+void mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder);
+
+/* return neg, 0, pos as b1-b2 is neg, 0, pos */
+int mpcmp(mpint *b1, mpint *b2);
+
+/* res = s != 0 ? b1 : b2 */
+void mpsel(int s, mpint *b1, mpint *b2, mpint *res);
+
+/* extended gcd return d, x, and y, s.t. d = gcd(a,b) and ax+by = d */
+void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y);
+
+/* res = b**-1 mod m */
+void mpinvert(mpint *b, mpint *m, mpint *res);
+
+/* bit counting */
+int mpsignif(mpint*); /* number of sigificant bits in mantissa */
+int mplowbits0(mpint*); /* k, where n = 2**k * q for odd q */
+
+/* well known constants */
+extern mpint *mpzero, *mpone, *mptwo;
+
+/* sum[0:alen] = a[0:alen-1] + b[0:blen-1] */
+/* prereq: alen >= blen, sum has room for alen+1 digits */
+void mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum);
+
+/* diff[0:alen-1] = a[0:alen-1] - b[0:blen-1] */
+/* prereq: alen >= blen, diff has room for alen digits */
+void mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff);
+
+/* p[0:n] += m * b[0:n-1] */
+/* prereq: p has room for n+1 digits */
+void mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p);
+
+/* p[0:n] -= m * b[0:n-1] */
+/* prereq: p has room for n+1 digits */
+int mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p);
+
+/* p[0:alen+blen-1] = a[0:alen-1] * b[0:blen-1] */
+/* prereq: alen >= blen, p has room for m*n digits */
+void mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
+void mpvectsmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
+
+/* sign of a - b or zero if the same */
+int mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen);
+int mpvectscmp(mpdigit *a, int alen, mpdigit *b, int blen);
+
+/* divide the 2 digit dividend by the one digit divisor and stick in quotient */
+/* we assume that the result is one digit - overflow is all 1's */
+void mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
+
+/* playing with magnitudes */
+int mpmagcmp(mpint *b1, mpint *b2);
+void mpmagadd(mpint *b1, mpint *b2, mpint *sum); /* sum = b1+b2 */
+void mpmagsub(mpint *b1, mpint *b2, mpint *sum); /* sum = b1+b2 */
+
+/* chinese remainder theorem */
+typedef struct CRTpre CRTpre; /* precomputed values for converting */
+ /* twixt residues and mpint */
+typedef struct CRTres CRTres; /* residue form of an mpint */
+
+#pragma incomplete CRTpre
+
+struct CRTres
+{
+ int n; /* number of residues */
+ mpint *r[1]; /* residues */
+};
+
+CRTpre* crtpre(int, mpint**); /* precompute conversion values */
+CRTres* crtin(CRTpre*, mpint*); /* convert mpint to residues */
+void crtout(CRTpre*, CRTres*, mpint*); /* convert residues to mpint */
+void crtprefree(CRTpre*);
+void crtresfree(CRTres*);
+
+/* fast field arithmetic */
+typedef struct Mfield Mfield;
+
+struct Mfield
+{
+ mpint;
+ int (*reduce)(Mfield*, mpint*, mpint*);
+};
+
+mpint *mpfield(mpint*);
+
+Mfield *gmfield(mpint*);
+Mfield *cnfield(mpint*);
+
+#pragma varargck type "B" mpint*
+
+#endif
--- a/sys/include/ape/u.h
+++ b/sys/include/ape/u.h
@@ -16,4 +16,9 @@
typedef union FPdbleword FPdbleword;
typedef char* p9va_list;
+typedef uchar u8int;
+typedef ushort u16int;
+typedef ulong u32int;
+typedef uvlong u64int;
+
#endif
--- /dev/null
+++ b/sys/src/ape/lib/9/ctime.c
@@ -1,0 +1,22 @@
+#include "libc.h"
+
+#undef gmtime
+
+Tm*
+_gmtime(time_t t)
+{
+ static Tm r;
+ struct tm *p;
+
+ p = gmtime(&t);
+ r.sec = p->tm_sec;
+ r.min = p->tm_min;
+ r.hour = p->tm_hour;
+ r.mday = p->tm_mday;
+ r.mon = p->tm_mon;
+ r.year = p->tm_year;
+ r.wday = p->tm_wday;
+ r.yday = p->tm_yday;
+ strcpy(r.zone, "GMT");
+ return &r;
+}
--- a/sys/src/ape/lib/9/libc.h
+++ b/sys/src/ape/lib/9/libc.h
@@ -1,6 +1,11 @@
#define _LOCK_EXTENSION
#define _QLOCK_EXTENSION
#define _BSD_EXTENSION
+
+#ifdef _NET_EXTENSION
+#include <libnet.h>
+#endif
+
#include <stdint.h>
#include <sys/types.h>
#include <lock.h>
@@ -15,6 +20,7 @@
#include <utf.h>
#include <fmt.h>
#include <signal.h>
+#include <time.h>
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
@@ -54,6 +60,17 @@
void _nulldir(Dir*);
uint _sizeD2M(Dir*);
+#define convM2D _convM2D
+#define convD2M _convD2M
+#define dirstat _dirstat
+#define dirwstat _dirwstat
+#define dirfstat _dirfstat
+#define dirfwstat _dirfwstat
+#define dirread _dirread
+#define dirreadall _dirreadall
+#define nulldir _nulldir
+#define sizeD2M _sizeD2M
+
typedef
struct Waitmsg
{
@@ -62,7 +79,6 @@
char *msg;
} Waitmsg;
-
extern int _AWAIT(char*, int);
extern int _ALARM(unsigned long);
extern int _BIND(const char*, const char*, int);
@@ -106,13 +122,14 @@
extern int _IOUNIT(int);
extern vlong _NSEC(void);
-#define dirstat _dirstat
-#define dirfstat _dirfstat
-
#define OREAD 0
#define OWRITE 1
#define ORDWR 2
-#define OCEXEC 32
+#define OEXEC 3 /* execute, == read but check execute permission */
+#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
+#define OCEXEC 32 /* or'ed in, close on exec */
+#define ORCLOSE 64 /* or'ed in, remove on close */
+#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
#define AREAD 4
#define AWRITE 2
@@ -125,6 +142,8 @@
#define create(file, omode, perm) open(file, (omode) |O_CREAT | O_TRUNC, perm)
#define seek(fd, off, dir) lseek(fd, off, dir)
+#define fauth _FAUTH
+#define wait _WAIT
#define readn _READN
#define pread _PREAD
#define pwrite _PWRITE
@@ -132,11 +151,15 @@
#define nsec _NSEC
#define iounit _IOUNIT
+#define getwd(buf,len) getcwd(buf,len)
#define postnote(who,pid,note) kill(pid,SIGTERM)
#define atnotify(func,in)
#define ERRMAX 128
+int errstr(char*, unsigned int);
+extern void sysfatal(char*, ...);
+
extern void setmalloctag(void*, uintptr_t);
extern void setrealloctag(void*, uintptr_t);
extern uintptr_t getcallerpc(void*);
@@ -148,6 +171,29 @@
extern int dec64(uchar *, int, char *, int);
extern int enc64(char *, int, uchar *, int);
-extern int tokenize(char*, char**, int);
-extern void sysfatal(char*, ...);
-extern ulong truerand(void); /* uses /dev/random */
+extern int tokenize(char*, char**, int);
+extern int getfields(char*, char**, int, int, char*);
+extern int gettokens(char*, char**, int, char*);
+
+extern ulong truerand(void); /* uses /dev/random */
+
+extern int encrypt(void*, void*, int len);
+extern int decrypt(void*, void*, int len);
+
+typedef
+struct Tm
+{
+ int sec;
+ int min;
+ int hour;
+ int mday;
+ int mon;
+ int year;
+ int wday;
+ int yday;
+ char zone[4];
+ int tzoff;
+} Tm;
+
+Tm* _gmtime(time_t);
+#define gmtime _gmtime
--- a/sys/src/ape/lib/9/mkfile
+++ b/sys/src/ape/lib/9/mkfile
@@ -2,11 +2,15 @@
<$APE/config
LIB=/$objtype/lib/ape/lib9.a
-OFILES=argv0.$O\
- errstr.$O\
+OFILES=\
+ argv0.$O\
bind.$O\
+ crypt.$O\
+ ctime.$O\
+ errstr.$O\
getcallerpc.$O\
getfcr.$O\
+ getfields.$O\
mount.$O\
rendezvous.$O\
rfork.$O\
@@ -40,8 +44,14 @@
sysfatal.$O: ../../../libc/9sys/sysfatal.c
$CC $CFLAGS -I. ../../../libc/9sys/sysfatal.c
+getfields.$O: ../../../libc/port/getfields.c
+ $CC $CFLAGS -I. ../../../libc/port/getfields.c
+
tokenize.$O: ../../../libc/port/tokenize.c
$CC $CFLAGS -I. ../../../libc/port/tokenize.c
+
+crypt.$O: ../../../libc/port/crypt.c
+ $CC $CFLAGS -I. ../../../libc/port/crypt.c
truerand.$O: ../../../libc/9sys/truerand.c
$CC $CFLAGS -I. ../../../libc/9sys/truerand.c
--- /dev/null
+++ b/sys/src/ape/lib/auth/authsrv.h
@@ -1,0 +1,45 @@
+enum
+{
+ ANAMELEN= 28, /* name max size in previous proto */
+ AERRLEN= 64, /* errstr max size in previous proto */
+ DOMLEN= 48, /* authentication domain name length */
+ DESKEYLEN= 7, /* encrypt/decrypt des key length */
+ AESKEYLEN= 16, /* encrypt/decrypt aes key length */
+
+ CHALLEN= 8, /* plan9 sk1 challenge length */
+ NETCHLEN= 16, /* max network challenge length (used in AS protocol) */
+ CONFIGLEN= 14,
+ SECRETLEN= 32, /* secret max size */
+
+ NONCELEN= 32,
+
+ KEYDBOFF= 8, /* bytes of random data at key file's start */
+ OKEYDBLEN= ANAMELEN+DESKEYLEN+4+2, /* old key file entry length */
+ KEYDBLEN= OKEYDBLEN+SECRETLEN, /* key file entry length */
+ OMD5LEN= 16,
+
+ /* AuthPAK constants */
+ PAKKEYLEN= 32,
+ PAKSLEN= (448+7)/8, /* ed448 scalar */
+ PAKPLEN= 4*PAKSLEN, /* point in extended format X,Y,Z,T */
+ PAKHASHLEN= 2*PAKPLEN, /* hashed points PM,PN */
+ PAKXLEN= PAKSLEN, /* random scalar secret key */
+ PAKYLEN= PAKSLEN, /* decaf encoded public key */
+};
+
+typedef struct Authkey Authkey;
+struct Authkey
+{
+ char des[DESKEYLEN]; /* DES key from password */
+ uchar aes[AESKEYLEN]; /* AES key from password */
+ uchar pakkey[PAKKEYLEN]; /* shared key from AuthPAK exchange (see authpak_finish()) */
+ uchar pakhash[PAKHASHLEN]; /* secret hash from AES key and user name (see authpak_hash()) */
+};
+
+/*
+ * convert ascii password to auth key
+ */
+extern void passtokey(Authkey*, char*);
+
+extern void passtodeskey(char key[DESKEYLEN], char *p);
+extern void passtoaeskey(uchar key[AESKEYLEN], char *p);
--- /dev/null
+++ b/sys/src/ape/lib/auth/fcall.h
@@ -1,0 +1,20 @@
+#define VERSION9P "9P2000"
+#define MAXWELEM 16
+
+#define GBIT8(p) ((p)[0])
+#define GBIT16(p) ((p)[0]|((p)[1]<<8))
+#define GBIT32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
+#define GBIT64(p) ((u32int)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
+ ((vlong)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
+
+#define PBIT8(p,v) (p)[0]=(v)
+#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
+#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
+#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
+ (p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
+
+#define BIT8SZ 1
+#define BIT16SZ 2
+#define BIT32SZ 4
+#define BIT64SZ 8
+#define QIDSZ (BIT8SZ+BIT32SZ+BIT64SZ)
--- /dev/null
+++ b/sys/src/ape/lib/auth/mkfile
@@ -1,0 +1,43 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libauth.a
+OFILES=\
+ amount.$O\
+ amount_getkey.$O\
+ attr.$O\
+ auth_attr.$O\
+ auth_challenge.$O\
+ auth_chuid.$O\
+ auth_getkey.$O\
+ auth_getuserpasswd.$O\
+ auth_proxy.$O\
+ auth_respond.$O\
+ auth_rpc.$O\
+ auth_userpasswd.$O\
+ auth_wep.$O\
+ login.$O\
+ newns.$O\
+ noworld.$O\
+ passtokey.$O\
+
+HFILES=\
+ /sys/include/ape/auth.h\
+ /sys/src/libauth/authlocal.h\
+ ../9/libc.h
+
+UPDATE=\
+ mkfile\
+ $HFILES\
+ ${OFILES:%.$O=%.c}\
+ ${LIB:/$objtype/%=/386/%}\
+
+</sys/src/cmd/mksyslib
+
+CFLAGS=-TVwc -D_POSIX_SOURCE -D_PLAN9_SOURCE -D_NET_EXTENSION -I. -I../9 -I/sys/src/libauth
+
+%.$O: /sys/src/libauth/%.c
+ $CC $CFLAGS /sys/src/libauth/$stem.c
+
+passtokey.$O: /sys/src/libauthsrv/passtokey.c
+ $CC $CFLAGS /sys/src/libauthsrv/passtokey.c
--- /dev/null
+++ b/sys/src/ape/lib/bio/mkfile
@@ -1,0 +1,38 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libbio.a
+OFILES=\
+ bbuffered.$O\
+ bfildes.$O\
+ bflush.$O\
+ bgetrune.$O\
+ bgetc.$O\
+# bgetd.$O\
+ binit.$O\
+ blethal.$O\
+ boffset.$O\
+ bprint.$O\
+ bputrune.$O\
+ bputc.$O\
+ brdline.$O\
+ brdstr.$O\
+ bread.$O\
+ bseek.$O\
+ bwrite.$O\
+ bvprint.$O\
+
+HFILES=/sys/include/ape/bio.h
+
+UPDATE=\
+ mkfile\
+ $HFILES\
+ ${OFILES:%.$O=%.c}\
+ ${LIB:/$objtype/%=/386/%}\
+
+</sys/src/cmd/mksyslib
+
+CFLAGS=-TVwc -D_PLAN9_SOURCE -D_POSIX_SOURCE -I. -I../9
+
+%.$O: /sys/src/libbio/%.c
+ $CC $CFLAGS /sys/src/libbio/$stem.c
--- /dev/null
+++ b/sys/src/ape/lib/mp/386/mkfile
@@ -1,0 +1,26 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+SFILES=\
+ mpvecadd.s\
+ mpvecdigmuladd.s\
+ mpvecdigmulsub.s\
+ mpvecsub.s\
+ mpdigdiv.s\
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: ../../../../libmp/386/%.s
+ $AS ../../../../libmp/386/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/mp/alpha/mkfile
@@ -1,0 +1,15 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=\
+
+UPDATE=mkfile\
+ $HFILES\
+
+</sys/src/cmd/mksyslib
--- /dev/null
+++ b/sys/src/ape/lib/mp/amd64/mkfile
@@ -1,0 +1,26 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+SFILES=\
+ mpvecadd.s\
+ mpvecdigmuladd.s\
+ mpvecdigmulsub.s\
+ mpvecsub.s\
+ mpdigdiv.s\
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: ../../../../libmp/amd64/%.s
+ $AS ../../../../libmp/amd64/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/mp/arm/mkfile
@@ -1,0 +1,21 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+SFILES=mpvecdigmuladd.s mpvecdigmulsub.s mpvecadd.s mpvecsub.s
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: ../../../../libmp/arm/%.s
+ $AS ../../../../libmp/arm/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/mp/mips/mkfile
@@ -1,0 +1,26 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+SFILES=\
+ mpvecadd.s\
+ mpvecsub.s\
+ mpvecdigmuladd.s\
+ mpvecdigmulsub.s\
+# mpdigdiv.s\
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: ../../../../libmp/mips/%.s
+ $AS ../../../../libmp/mips/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/mp/mkfile
@@ -1,0 +1,54 @@
+APE=/sys/src/ape
+<$APE/config
+
+DIRS=port $CPUS
+
+default:V: all
+
+install all:V:
+ for(i in port $objtype)@{
+ echo $i
+ cd $i
+ mk $MKFLAGS $target
+ }
+
+nuke:V: clean
+ rm -f /$objtype/lib/ape/libmp.a
+
+clean:V:
+ for(i in $DIRS)@{
+ echo $i
+ cd $i
+ mk $MKFLAGS $target
+ }
+
+installall:V:
+ for(objtype in $CPUS) mk $MKFLAGS install
+
+everything:V:
+ rm -f */*.[$OS]
+ for(objtype in 386)@{
+ echo $objtype
+ mk $MKFLAGS install
+ }
+ rm -f */*.[$OS]
+
+test.$O: ../../../libmp/test.c /sys/include/ape/mp.h ../../../libmp/port/dat.h
+ $CC -c -D_POSIX_SOURCE -D_PLAN9_SOURCE -I../9 -I../../../libmp/port ../../../libmp/test.c
+
+$O.test: test.$O /$objtype/lib/ape/libmp.a
+ $LD -o $O.test test.$O
+
+bigtest.$O: ../../../libmp/bigtest.c /sys/include/ape/mp.h ../../../libmp/port/dat.h
+ $CC -c -D_POSIX_SOURCE -D_PLAN9_SOURCE -I../9 -I../../../libmp/port ../../../libmp/bigtest.c
+
+$O.bigtest: bigtest.$O /$objtype/lib/ape/libmp.a
+ $LD -o $O.bigtest bigtest.$O
+
+allout:
+ objtype=386; mk; mk 8.test 8.bigtest
+ objtype=amd64; mk; mk 6.test 6.bigtest
+ objtype=arm; mk; mk 5.test 5.bigtest
+
+cleanout:
+ rm -f [568].* *.[568]
--- /dev/null
+++ b/sys/src/ape/lib/mp/port/mkfile
@@ -1,0 +1,72 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+FILES=\
+ mpaux\
+ mpfmt\
+ strtomp\
+ mptobe\
+ mptober\
+ mptole\
+ mptolel\
+ betomp\
+ letomp\
+ mpadd\
+ mpsub\
+ mpcmp\
+ mpsel\
+ mpfactorial\
+ mpmul\
+ mpleft\
+ mpright\
+ mpvecadd\
+ mpvecsub\
+ mpvecdigmuladd\
+ mpveccmp\
+ mpvectscmp\
+ mpdigdiv\
+ mpdiv\
+ mpexp\
+ mpmod\
+ mpmodop\
+ mpextendedgcd\
+ mpinvert\
+ mprand\
+ mpnrand\
+ crt\
+ mptoi\
+ mptoui\
+ mptov\
+ mptouv\
+ mpfield\
+ cnfield\
+ gmfield\
+ mplogic\
+
+ALLOFILES=${FILES:%=%.$O}
+
+# cull things in the per-machine directories from this list
+OFILES= `{rfork en; \
+ if(~ $objtype spim) objtype=mips; \
+ bind -a ../../../../libmp/$objtype ../$objtype; \
+ rc ../../../../libmp/port/reduce $O $objtype $ALLOFILES}
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h\
+
+CFILES=${FILES:%=%.c}
+
+UPDATE=\
+ mkfile\
+ $HFILES\
+ $CFILES\
+
+</sys/src/cmd/mksyslib
+
+CFLAGS=-TVwc -+ -D_POSIX_SOURCE -D_PLAN9_SOURCE -I. -I../../9
+
+%.$O: ../../../../libmp/port/%.c
+ $CC $CFLAGS ../../../../libmp/port/$stem.c
--- /dev/null
+++ b/sys/src/ape/lib/mp/power/mkfile
@@ -1,0 +1,25 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+SFILES=\
+ mpvecadd.s\
+ mpvecsub.s\
+ mpvecdigmuladd.s\
+ mpvecdigmulsub.s\
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: ../../../../libmp/power/%.s
+ $AS ../../../../libmp/power/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/mp/spim/mkfile
@@ -1,0 +1,26 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libmp.a
+
+SFILES=\
+ mpvecadd.s\
+ mpvecsub.s\
+ mpvecdigmuladd.s\
+ mpvecdigmulsub.s\
+# mpdigdiv.s\
+
+HFILES=\
+ /sys/include/ape/mp.h\
+ ../../../../libmp/port/dat.h
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: ../../../../libmp/mips/%.s
+ $AS ../../../../libmp/mips/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/386/mkfile
@@ -1,0 +1,23 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+FILES=\
+ md5block\
+ sha1block\
+
+HFILES=/sys/include/ape/libsec.h
+
+SFILES=${FILES:%=%.s}
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: /sys/src/libsec/$objtype/%.s
+ $AS $AFLAGS /sys/src/libsec/$objtype/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/alpha/mkfile
@@ -1,0 +1,15 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+OFILES= \
+
+HFILES=/sys/include/ape/libsec.h
+
+UPDATE=mkfile
+
+</sys/src/cmd/mksyslib
+
+%.$O: /sys/src/libsec/$objtype/%.s
+ $AS $AFLAGS /sys/src/libsec/$objtype/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/amd64/mkfile
@@ -1,0 +1,22 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+FILES=\
+ md5block\
+ sha1block\
+
+HFILES=/sys/include/ape/libsec.h
+
+SFILES=${FILES:%=%.s}
+
+OFILES=${FILES:%=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: /sys/src/libsec/$objtype/%.s
+ $AS $AFLAGS /sys/src/libsec/$objtype/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/arm/mkfile
@@ -1,0 +1,15 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+OFILES= \
+
+HFILES=/sys/include/ape/libsec.h
+
+UPDATE=mkfile
+
+</sys/src/cmd/mksyslib
+
+%.$O: /sys/src/libsec/$objtype/%.s
+ $AS $AFLAGS /sys/src/libsec/$objtype/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/mips/mkfile
@@ -1,0 +1,23 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+FILES=\
+ md5block\
+ sha1block\
+
+HFILES=/sys/include/ape/libsec.h
+
+SFILES=${FILES:%=%.s}
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+%.$O: /sys/src/libsec/$objtype/%.s
+ $AS $AFLAGS /sys/src/libsec/$objtype/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/mkfile
@@ -1,0 +1,46 @@
+</$objtype/mkfile
+
+DIRS=port $CPUS
+
+default:V: all
+
+install all:V:
+ for(i in port $objtype)@{
+ echo $i
+ cd $i
+ mk $MKFLAGS $target
+ }
+
+clean:V:
+ for(i in $DIRS)@{
+ echo $i
+ cd $i
+ mk $MKFLAGS $target
+ }
+
+nuke:V: clean
+ rm -f /$objtype/lib/libsec.a
+
+update:V:
+ for(i in $DIRS)@{
+ echo $i
+ cd $i
+ mk $MKFLAGS update
+ }
+ update $UPDATEFLAGS /386/lib/libsec.a
+
+installall:V:
+ for(objtype in $CPUS) mk $MKFLAGS install
+
+everything:V:
+ rm -f */*.[$OS]
+ for(objtype in $CPUS)@{
+ echo $objtype
+ mk $MKFLAGS install
+ }
+ rm -f */*.[$OS]
+
+APE=/sys/src/ape
+<$APE/config
+$O.tlsclient: tlsclient.c
+ $CC -o $target $CFLAGS -D_POSIX_SOURCE -D_PLAN9_SOURCE -D_NET_EXTENSION tlsclient.c
--- /dev/null
+++ b/sys/src/ape/lib/sec/port/mkfile
@@ -1,0 +1,72 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+CFILES = des.c desmodes.c desECB.c desCBC.c des3ECB.c des3CBC.c\
+ aes.c aes_gcm.c blowfish.c \
+ hmac.c md5.c md5block.c md4.c sha1.c sha1block.c\
+ sha2_64.c sha2_128.c sha2block64.c sha2block128.c\
+ sha1pickle.c md5pickle.c\
+ poly1305.c\
+ rc4.c\
+ chacha.c\
+ salsa.c\
+ genrandom.c prng.c fastrand.c nfastrand.c\
+ probably_prime.c smallprimetest.c genprime.c dsaprimes.c\
+ gensafeprime.c genstrongprime.c\
+ rsagen.c rsafill.c rsaencrypt.c rsadecrypt.c rsaalloc.c \
+ rsaprivtopub.c \
+ x509.c \
+ decodepem.c \
+ eggen.c egencrypt.c egdecrypt.c egalloc.c egprivtopub.c \
+ egsign.c egverify.c \
+ dsagen.c dsaalloc.c dsaprivtopub.c dsasign.c dsaverify.c \
+ tlshand.c \
+ thumb.c readcert.c \
+ aes_xts.c \
+ ecc.c\
+ ripemd.c\
+ dh.c\
+ curve25519.c\
+ curve25519_dh.c\
+ pbkdf2.c\
+ hkdf.c\
+ ccpoly.c\
+ tsmemcmp.c\
+ secp256r1.c\
+ secp256k1.c\
+
+CLEANFILES=secp256r1.c secp256k1.c
+
+ALLOFILES=${CFILES:%.c=%.$O}
+
+# cull things in the per-machine directories from this list
+OFILES= `{rfork n; \
+ bind -a ../../../../libsec/$objtype ../$objtype; \
+ rc ../../../../libsec/port/reduce $O $objtype $ALLOFILES}
+
+HFILES=/sys/include/ape/libsec.h
+
+UPDATE=mkfile\
+ $HFILES\
+ $CFILES\
+
+</sys/src/cmd/mksyslib
+
+CFLAGS=-TVwc -+ -D_POSIX_SOURCE -D_PLAN9_SOURCE -I. -I../../9 -I../../../../libmp/port
+
+../../../../libsec/port/%.c:D: ../../../../libsec/port/%.mp
+ @{cd ../../../../libsec/port && mk $stem.c}
+
+%.$O: ../../../../libsec/port/%.c
+ $CC $CFLAGS ../../../../libsec/port/$stem.c
+
+$O.rsatest: rsatest.$O
+ $LD -o $target $prereq
+
+$O.chachatest: chachatest.$O
+ $LD -o $target $prereq
+
+$O.aesgcmtest: aesgcmtest.$O
+ $LD -o $target $prereq
--- /dev/null
+++ b/sys/src/ape/lib/sec/power/mkfile
@@ -1,0 +1,15 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+OFILES= \
+
+HFILES=/sys/include/ape/libsec.h
+
+UPDATE=mkfile
+
+</sys/src/cmd/mksyslib
+
+%.$O: /sys/src/libsec/$objtype/%.s
+ $AS $AFLAGS /sys/src/libsec/$objtype/$stem.s
--- /dev/null
+++ b/sys/src/ape/lib/sec/spim/mkfile
@@ -1,0 +1,12 @@
+APE=/sys/src/ape
+<$APE/config
+
+LIB=/$objtype/lib/ape/libsec.a
+
+HFILES=/sys/include/ape/libsec.h
+
+OFILES=\
+
+UPDATE=mkfile $HFILES
+
+</sys/src/cmd/mksyslib
--- /dev/null
+++ b/sys/src/ape/lib/sec/tlsclient.c
@@ -1,0 +1,177 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <lib9.h>
+
+#include <libsec.h>
+#include <libnet.h>
+
+#include <auth.h>
+
+int debug, auth, dialfile;
+char *keyspec = "";
+char *servername, *file, *filex, *ccert;
+
+void
+sysfatal(char *fmt, ...)
+{
+ va_list a;
+
+ va_start(a, fmt);
+ vfprintf(stderr, fmt, a);
+ va_end(a);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: tlsclient [-D] [-a [-k keyspec] ] [-c lib/tls/clientcert] [-t /sys/lib/tls/xxx] [-x /sys/lib/tls/xxx.exclude] [-n servername] [-o] dialstring [cmd [args...]]\n");
+ exit(1);
+}
+
+void
+xfer(int from, int to)
+{
+ char buf[12*1024];
+ int n;
+
+ while((n = read(from, buf, sizeof buf)) > 0)
+ if(write(to, buf, n) < 0)
+ break;
+}
+
+static int
+reporter(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprint(2, "%s: tls reports ", argv0);
+ vfprint(2, fmt, ap);
+ fprint(2, "\n");
+
+ va_end(ap);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd, pid;
+ char *addr;
+ TLSconn *conn;
+ Thumbprint *thumb;
+ AuthInfo *ai = nil;
+
+// fmtinstall('H', encodefmt);
+
+ ARGBEGIN{
+ case 'D':
+ debug++;
+ break;
+ case 'a':
+ auth++;
+ break;
+ case 'k':
+ keyspec = EARGF(usage());
+ break;
+ case 't':
+ file = EARGF(usage());
+ break;
+ case 'x':
+ filex = EARGF(usage());
+ break;
+ case 'c':
+ ccert = EARGF(usage());
+ break;
+ case 'n':
+ servername = EARGF(usage());
+ break;
+ case 'o':
+ dialfile = 1;
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ if(argc < 1)
+ usage();
+
+ if(filex && !file)
+ sysfatal("specifying -x without -t is useless");
+
+ if(file){
+ thumb = initThumbprints(file, filex);
+ if(thumb == nil)
+ sysfatal("initThumbprints: %r");
+ } else
+ thumb = nil;
+
+ addr = *argv++;
+ if((fd = dial(addr, 0, 0, 0)) < 0)
+ sysfatal("dial %s: %r", addr);
+
+ conn = (TLSconn*)malloc(sizeof *conn);
+ memset(conn, 0, sizeof(*conn));
+ conn->serverName = servername;
+ if(ccert){
+ conn->cert = readcert(ccert, &conn->certlen);
+ if(conn->cert == nil)
+ sysfatal("readcert: %r");
+ }
+
+ if(auth){
+ ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client %s", keyspec);
+ if(ai == nil)
+ sysfatal("auth_proxy: %r");
+
+ conn->pskID = "p9secret";
+ conn->psk = ai->secret;
+ conn->psklen = ai->nsecret;
+ }
+
+ if(debug)
+ conn->trace = reporter;
+
+ fd = tlsClient(fd, conn);
+ if(fd < 0)
+ sysfatal("tlsclient: %r");
+
+ if(thumb){
+ uchar digest[20];
+
+ if(conn->cert==nil || conn->certlen<=0)
+ sysfatal("server did not provide TLS certificate");
+ sha1(conn->cert, conn->certlen, digest, nil);
+ if(!okThumbprint(digest, thumb))
+ sysfatal("server certificate %.*H not recognized", SHA1dlen, digest);
+ freeThumbprints(thumb);
+ }
+
+ free(conn->cert);
+ free(conn->sessionID);
+ free(conn);
+ if(ai != nil)
+ auth_freeAI(ai);
+
+ pid = fork();
+ switch(pid){
+ case -1:
+ sysfatal("fork: %r");
+ case 0:
+ pid = getppid();
+ xfer(0, fd);
+ break;
+ default:
+ xfer(fd, 1);
+ break;
+ }
+ if(pid) kill(pid, SIGTERM);
+ return 0;
+}