diff options
| author | forsyth <forsyth@vitanuova.com> | 2011-04-03 15:03:05 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2011-04-03 15:03:05 +0100 |
| commit | 728860af799ffd5aa8b3b90576ae582b11b7f5a5 (patch) | |
| tree | b6e969a01af2a3d56d7296b96002476dd116fa8d | |
| parent | 41858f31398f2a5187173202c165df7717217c89 (diff) | |
20110403-1502
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | appl/cmd/auth/mkfile | 1 | ||||
| -rw-r--r-- | appl/cmd/auth/secstore.b | 28 | ||||
| -rw-r--r-- | appl/lib/secstore.b | 42 | ||||
| -rw-r--r-- | dis/auth/secstore.dis | bin | 5584 -> 6464 bytes | |||
| -rw-r--r-- | dis/lib/secstore.dis | bin | 8361 -> 8956 bytes | |||
| -rw-r--r-- | include/version.h | 2 | ||||
| -rw-r--r-- | man/2/secstore | 31 | ||||
| -rw-r--r-- | module/secstore.m | 4 |
9 files changed, 104 insertions, 6 deletions
@@ -1,3 +1,5 @@ +20110403 + secstore(2) and secstore(1) updated to implement writing [issue 256, mechiel] 20110402 revision to devsrv.c change [issue 244] to avoid two calls to delwaiting 20110330 diff --git a/appl/cmd/auth/mkfile b/appl/cmd/auth/mkfile index 71d31533..40eaf557 100644 --- a/appl/cmd/auth/mkfile +++ b/appl/cmd/auth/mkfile @@ -17,6 +17,7 @@ TARG=\ mkauthinfo.dis\ passwd.dis\ rsagen.dis\ + secstore.dis\ signer.dis\ verify.dis\ diff --git a/appl/cmd/auth/secstore.b b/appl/cmd/auth/secstore.b index e26e132d..3bebd29b 100644 --- a/appl/cmd/auth/secstore.b +++ b/appl/cmd/auth/secstore.b @@ -199,7 +199,25 @@ Auth: secstore->erasekey(file); file = nil; verb('x', fname); - 'r' or * => + 'r' => + checkname(fname, 1); + fd := sys->open(fname, sys->OREAD); + if(fd == nil) + error(sys->sprint("open %q: %r", fname)); + (ok, dir) := sys->fstat(fd); + if(ok != 0) + error(sys->sprint("stat %q: %r", fname)); + if(int dir.length > Maxfilesize) + error(sys->sprint("length %bd > Maxfilesize %d", dir.length, Maxfilesize)); + file = array[int dir.length] of byte; + if(sys->readn(fd, file, len file) != len file) + error(sys->sprint("short read: %r")); + if(putfile(conn, fname, file, filekey) < 0) + error(sys->sprint("putfile: %r")); + secstore->erasekey(file); + file = nil; + verb('r', fname); + * => error(sys->sprint("op %c not implemented", op)); } } @@ -242,6 +260,14 @@ getfile(conn: ref Dial->Connection, fname: string, key: array of byte): array of return f; } +putfile(conn: ref Dial->Connection, fname: string, data, key: array of byte): int +{ + data = secstore->encrypt(data, key); + if(data == nil) + return -1; + return secstore->putfile(conn, fname, data); +} + erase() { if(secstore != nil){ diff --git a/appl/lib/secstore.b b/appl/lib/secstore.b index f6cb1b15..21ee45c8 100644 --- a/appl/lib/secstore.b +++ b/appl/lib/secstore.b @@ -17,6 +17,7 @@ include "keyring.m"; include "security.m"; ssl: SSL; + random: Random; include "encoding.m"; base64: Encoding; @@ -29,6 +30,7 @@ init() sys = load Sys Sys->PATH; kr = load Keyring Keyring->PATH; ssl = load SSL SSL->PATH; + random = load Random Random->PATH; base64 = load Encoding Encoding->BASE64PATH; dialler = load Dial Dial->PATH; initPAKparams(); @@ -183,6 +185,28 @@ remove(conn: ref Dial->Connection, name: string): int return 0; } +putfile(conn: ref Dial->Connection, name: string, data: array of byte): int +{ + if(len data > Maxfilesize){ + sys->werrstr("file too long"); + return -1; + } + fd := conn.dfd; + if(sys->fprint(fd, "PUT %s\n", name) < 0) + return -1; + if(sys->fprint(fd, "%d", len data) < 0) + return -1; + for(o := 0; o < len data;){ + n := len data-o; + if(n > Maxmsg) + n = Maxmsg; + if(sys->write(fd, data[o:o+n], n) != n) + return -1; + o += n; + } + return 0; +} + bye(conn: ref Dial->Connection) { if(conn != nil){ @@ -236,6 +260,24 @@ decrypt(file: array of byte, key: array of byte): array of byte return file[AESbsize: length-Checklen]; } +encrypt(file: array of byte, key: array of byte): array of byte +{ + dat := array[AESbsize+len file+Checklen] of byte; + iv := random->randombuf(random->NotQuiteRandom, AESbsize); + if(len iv != AESbsize) + return nil; + dat[:] = iv; + dat[len iv:] = file; + dat[len iv+len file:] = array of byte Checkpat; + state := kr->aessetup(key, iv); + if(state == nil){ + sys->werrstr("can't set AES state"); + return nil; + } + kr->aescbc(state, dat[AESbsize:], len dat-AESbsize, Keyring->Encrypt); + return dat; +} + lines(file: array of byte): list of array of byte { rl: list of array of byte; diff --git a/dis/auth/secstore.dis b/dis/auth/secstore.dis Binary files differindex 3edff631..14dba10a 100644 --- a/dis/auth/secstore.dis +++ b/dis/auth/secstore.dis diff --git a/dis/lib/secstore.dis b/dis/lib/secstore.dis Binary files differindex 1a76220c..f24894ce 100644 --- a/dis/lib/secstore.dis +++ b/dis/lib/secstore.dis diff --git a/include/version.h b/include/version.h index 8dc0abc6..5fc67c53 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define VERSION "Fourth Edition (20110402)" +#define VERSION "Fourth Edition (20110403)" diff --git a/man/2/secstore b/man/2/secstore index d6395955..6bb11674 100644 --- a/man/2/secstore +++ b/man/2/secstore @@ -23,13 +23,13 @@ files: fn(conn: ref Dial->Connection): list of (string, int, string, string, array of byte); getfile: fn(conn: ref Dial->Connection, name: string, maxsize: int): array of byte; -.\"putfile: fn(conn: ref Dial->Connection, name: string, data: array of byte,): int; +putfile: fn(conn: ref Dial->Connection, name: string, data: array of byte): int; remove: fn(conn: ref Dial->Connection, file: string): int; bye: fn(conn: ref Dial->Connection); mkfilekey: fn(pass: string): array of byte; decrypt: fn(data: array of byte, filekey: array of byte): array of byte; -.\"encrypt: fn(data: array of byte, filekey: array of byte): array of byte; +encrypt: fn(data: array of byte, filekey: array of byte): array of byte; erasekey: fn(key: array of byte); lines: fn(file: array of byte): list of array of byte; @@ -193,6 +193,19 @@ is not the same value as the .I seckey used for initial authentication, although the secret text is the same.) .PP +.B Putfile +writes +.I data +under file +.I name +to the secure store, overwriting a possibly existing file by that name. +.I Data +should already be encrypted. +The caller can arrange this by calling +.BR encrypt . +.B Putfile +returns 0 on success and a negative value on error. +.PP .B Remove deletes the given .I file @@ -216,6 +229,19 @@ It returns nil if the file could not be decrypted (usually because the .I key value is not actually the encryption key). .PP +.B Encrypt +does the opposite of +.BR decrypt . +Given plain +.I data +and +.I filekey +produced by +.BR mkfilekey , +it returns an encrypted version of data, including headers and trailers. +This data is suitable for writing to the secure store with +.BR putfile . +.PP .B Erasekey clears the bytes of .I key @@ -247,5 +273,6 @@ closes the connection to the As well as returning the error values described above, functions set the system error string. .SH SEE ALSO .IR crypt (1), +.IR secstore (1), .IR factotum (2), .IR factotum (4) diff --git a/module/secstore.m b/module/secstore.m index 1cba9d1f..5a1ec52d 100644 --- a/module/secstore.m +++ b/module/secstore.m @@ -16,12 +16,12 @@ Secstore: module files: fn(conn: ref Dial->Connection): list of (string, int, string, string, array of byte); getfile: fn(conn: ref Dial->Connection, filename: string, maxsize: int): array of byte; remove: fn(conn: ref Dial->Connection, filename: string): int; -# putfile: fn(conn: ref Dial->Connection, filename: string, data: array of byte,): int; + putfile: fn(conn: ref Dial->Connection, filename: string, data: array of byte): int; bye: fn(conn: ref Dial->Connection); mkfilekey: fn(pass: string): array of byte; decrypt: fn(a: array of byte, key: array of byte): array of byte; -# encrypt: fn(a: array of byte, key: array of byte): array of byte; + encrypt: fn(a: array of byte, key: array of byte): array of byte; erasekey: fn(a: array of byte); lines: fn(file: array of byte): list of array of byte; |
