summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2011-04-03 15:03:05 +0100
committerforsyth <forsyth@vitanuova.com>2011-04-03 15:03:05 +0100
commit728860af799ffd5aa8b3b90576ae582b11b7f5a5 (patch)
treeb6e969a01af2a3d56d7296b96002476dd116fa8d
parent41858f31398f2a5187173202c165df7717217c89 (diff)
20110403-1502
-rw-r--r--CHANGES2
-rw-r--r--appl/cmd/auth/mkfile1
-rw-r--r--appl/cmd/auth/secstore.b28
-rw-r--r--appl/lib/secstore.b42
-rw-r--r--dis/auth/secstore.disbin5584 -> 6464 bytes
-rw-r--r--dis/lib/secstore.disbin8361 -> 8956 bytes
-rw-r--r--include/version.h2
-rw-r--r--man/2/secstore31
-rw-r--r--module/secstore.m4
9 files changed, 104 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index 29d4c7c8..36211cb7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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
index 3edff631..14dba10a 100644
--- a/dis/auth/secstore.dis
+++ b/dis/auth/secstore.dis
Binary files differ
diff --git a/dis/lib/secstore.dis b/dis/lib/secstore.dis
index 1a76220c..f24894ce 100644
--- a/dis/lib/secstore.dis
+++ b/dis/lib/secstore.dis
Binary files differ
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;